繁体   English   中英

在C ++中从头到尾将字符串分成两个一组

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM