预期的输出是 1a1b1c 但我只得到 1a1b 如果我尝试在 for 循环中将 '-1' 放在 input.size() 旁边,但这只会忽略该错误。我正在寻找的是我希望能够遍历字符串的最后一个成员而不会越界。
std::string input = "abc";
for (unsigned int i = 0; i < input.size(); i++){
int counter = 1;
while(input.at(i) == input.at(i+1) && i < input.size()-1){
counter++;
i++;
}
number.push_back(counter);
character.push_back(input.at(i));
}
有几点要注意:
1:for (unsigned int i = 0; i < input.size(); i++)
具体i++
。这是一个后缀操作,意味着它返回 i 然后增加 i 的值。对于整数,这里没有什么大不了的,但是对于迭代器,每次创建迭代器的副本时,这可能会变得非常昂贵。更喜欢说出你的意思/你真正想要什么,即增加 i,而不是获取 i 的副本并在之后增加 i。所以更喜欢++i
只增加 i 而不制作副本。
2:unsigned int i = 0
首先,它比使用具有有符号 -> 无符号对话的 int 更好,每次与input.size()
它的比较都返回 a size_t
。其次unsigned int
,不能保证足够大以容纳字符串的大小,并且需要从(可能)32 位提升 -> 64 位无符号以与 size_t 进行比较
3:认知复杂性,嵌套循环都改变了相同的不变量(在本例中为 i)使代码更难以推理,并且随着代码随着时间的推移最终会导致更多错误。在可能的情况下,只有一个循环不变量发生变异的地方。
4:正如其他人所指出的,while循环while(input.at(i) == input.at(i+1) && i < input.size()-1)
可以超过字符串的大小,使用字符串的.at
成员函数会抛出越界访问。这可以通过将嵌套循环重构为单个循环来简单地通过第 3 点解决。
5:避免对 进行如此多的调用.at
,我们完全控制用于索引字符串的索引,因此operator[]
只要我们能保证 i 始终是有效索引,您就可以安全使用,在这种情况下,我认为您可以。
6:i < input.size()
使用<
,当你想它不是检查和比你真正想要检查其昂贵得多i != input.size()
。在编译器资源管理器中查看这个微不足道的比较
谢天谢地,shadowranger 的修复完全解决了您的问题,即:while(i < s.size()-1 && s.at(i) == s.at(i+1))
但是我想提供一个没有嵌套循环的替代方案,以向您展示如何避免我的第 3、4、5 和 6 点:
void do_the_thing(std::string const& s) {
std::cout << "Considering: \"" + s + "\"\n";
if(s.empty()) {
return;
}
size_t const length = s.length(); // avoiding repeated calls to length which never changes in this case
if(length == 1) {
std::cout << "1" << s[0] << "\n";
return;
}
std::vector<unsigned> number;
std::vector<char> character;
// do the stuff your example did
char last = s[0];
unsigned same_count = 1;
for(size_t ii = 1; ii != length; ++ii) {
char const cur = s[ii];
if(cur == last) {
++same_count;
} else {
number.push_back(same_count);
character.push_back(last);
last = cur;
same_count = 1;
}
}
if(*s.rbegin() == last) {
number.push_back(same_count);
character.push_back(last);
}
// print the things or use them in some way
assert(number.size() == character.size());
size_t const out_len = character.size();
for(size_t ii = 0; ii != out_len; ++ii) {
std::cout << number[ii] << character[ii];
}
std::cout << "\n";
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句