[英]Splitting up a string from end to start into groups of two in C++
我很好奇我制作程序的方式,该程序接受一个字符串,然后检测它的结尾,然后开始将它“从结尾到开头”分成两部分? 例如,用户输入mskkllkkk ,并且输出必须为m sk kl lk kk 。
我尝试在网上搜索所需的工具,并熟悉了迭代器,并尝试将其用于此目的。 我做了这样的事情:
#include "iostream"
#include "string"
#include "conio.h"
int main() {
int k=0,i=-1;
std::string str1;
std::string::iterator PlaceCounter;
std::cin >> str1;
PlaceCounter = str1.end();
for (PlaceCounter; PlaceCounter != str1.begin(); --PlaceCounter)
{
++k;
if (k % 2 == 0 && k-1 != 0) {
++i;
str1.insert(str1.end()-k-i,' ');
}
}
std::cout << str1;
_getch();
return 0;
}
起初,当我输入几个任意情况时,它似乎工作得很好(可以将计算器中的所有三个数字从头到尾全部放入一组,从而使数字更易读,这样的事情可以准确地用在计算器中),但是突然我输入以下内容: jsfksdjfksdjfkdsjfskjdfkjsfn ,我得到了错误消息:“ 字符串迭代器不可减少 ”。
大概我需要为C ++学习更多的书,以便自己解决这个问题,但是现在我还是一个初学者,对此非常好奇。 为什么显示该错误信息? 提前致谢。
当您在字符串中insert()
,对其的迭代器可能会失效。 特别是在所有情况下,插入点之后的所有迭代器在所有情况下均应视为无效,但如果std::string
需要获得更多内存,则所有迭代器也会无效:内部缓冲区将被更大的缓冲区替换,从而导致所有现有的迭代器(以及引用和指针)指向要无效的字符串元素。
解决该问题的最简单方法是,通过reserve()
提前分配足够的空间来确保该字符串不需要分配更多的内存。 由于您每两个字符添加一个空格,因此请确保有足够的空间来str1.size() + str1.size() / 2u
字符:
str1.reserve(str1.size() + str1.size() / 2u);
for (auto PlaceCounter = str1.end(); PlaceCounter != str1.begin(); --PlaceCounter) {
// ...
}
请注意,您的算法效率很低:它是O(n 2 )。 该操作可以用O(n)复杂度来完成。 您将从一开始就将字符串的大小调整为适当的大小,在尾部填充一些默认字符,然后将内容从末尾直接复制到适当的位置。
str1.insert(str1.end()-k-i,' ');
这将修改循环迭代的字符串。 具体来说,这会在字符串中插入一些内容。
使用std::string
,非常类似于std::vector
,将其插入字符串将(可能)使所有指向该字符串的现有迭代器无效。 所显示的代码执行的第一次插入会导致未定义的行为,随后将引用现有的,现已失效的迭代器。
您将需要用字符串中的索引替换迭代器,或者代替修改现有字符串以构造新字符串,而保持原始字符串不变。
这是一种可能的C ++方法。 从我的工具包中,这是我如何将逗号插入十进制字符串(即s应该包含数字):
输入:“ 123456789”
// insert comma's from right (at implied decimal point) to left
std::string digiCommaL(std::string s)
{
// Note: decrementing a uint (such as size_t) will loop-around,
// and not underflow. Be sure to use int ...
int32_t sSize = static_cast<int32_t>(s.size()); // change to int
// ^^^^^-----------_____
if (sSize > 3) vvvvv
for (int32_t indx = (sSize - 3); indx > 0; indx -= 3)
s.insert(static_cast<size_t>(indx), 1, ',');
return(s);
}
返回:“ 123,456,789”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.