c++ - 使用 string erase() 和 string length() 从字符串中删除某些字符

标签 c++ string algorithm for-loop erase

我在下面编写了一个函数来遍历字符串 a 删除所有空格 ' ''-'。但是,它会跳过字符串的某些元素并在末尾留下 '-',因此逻辑一定是不正确的。谁能发现我哪里出错了?

#include <iostream>
#include <string>
using namespace std;

string FormatString(string S) { 

    size_t original_size = S.length();

    cout << "Length at start is " << S.length() << "\n";

    /*Count spaces and dashes*/
    for(size_t i = 0; i < S.length(); i++) {

        cout << "Current letter is " << S[i] << "\n";

        if((S[i] == ' ') || (S[i] == '-')) {
            cout << "Deleting current letter " << S[i] << "\n";
            S.erase (i,1);
            cout << "Length is now " << S.length() << "\n";

        }
    }

    std::cout << S << '\n';

    return S;
}


int main() {

    std::string testString("AA BB-4499--5");
    std::string result = FormatString(testString);
    cout << result << endl; // prints !!!Hello World!!!
    return 0;
}

输出是:

Length at start is 13
Current letter is A
Current letter is A
Current letter is  
Deleting current letter  
Length is now 12
Current letter is B
Current letter is -
Deleting current letter -
Length is now 11
Current letter is 4
Current letter is 9
Current letter is 9
Current letter is -
Deleting current letter -
Length is now 10
Current letter is 5
AABB4499-5
AABB4499-5

最佳答案

这是因为您在删除后增加了位置。

当您执行删除操作时,会将所有其他字符向下移动一个。如果您随后还增加了您在字符串中的位置,您实际上会跳过一个字符。

如果我们从这里开始:

"AA BB-4499--5"

删除几个字符后我们剩下这个

"AABB4499--5"
         ^           // i is 9.

您现在删除光标上方的字符。

"AABB4499-5"
         ^           // i is 9.

现在开始循环的下一次迭代。

"AABB4499-5"
          ^          // i is 10.

您注意到您跳过了一个字符。

这个算法更好的实现是:

for(size_t i = 0; i < S.length();) {     // Notice no increment here
    if((S[i] == ' ') || (S[i] == '-')) {
        S.erase (i,1);
    }
    else {
        ++i;
    }
}

我们可以用迭代器对此进行改进:

for(auto loop = std::begin(S); loop != std::end(S);) {
    if (*loop == ' ' || *loop == '-') {
        loop = S.erase(loop);
    }
    else {
        ++loop;
    }
}

现在我们正在使用迭代器,我们可以在标准算法中循环

auto newEnd = std::remove_if(std::begin(S), std::end(S),
                             [](char c){return c == ' ' || c == '-';});
std::erase(newEnd, std::end(S));

关于c++ - 使用 string erase() 和 string length() 从字符串中删除某些字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49558398/

相关文章:

c++ - 错误 : assignment of data-member ‘RootBoxT<CORE::DoubleWrapper>::innerBox_’ in read-only structure

c++ - 如何使用硬件加速在 Qt 中绘画?

python - 使用模式在 python 中版本字符串

python - 如何从Python中的列表中删除单引号

algorithm - 分布式系统中的锁定数据结构

c++ - 与 sizeof 派生类混淆

c# - 我有一个 c++ 代码需要翻译成 c#,几乎完成(我认为)但需要 P/Invoke 的帮助才能使用非托管 dll

java - 从Java中的文本文件中按升序排列字母

Java:测试算法:所有可能的组合

c++ - 如何使用 CUDA 实现 2-for 粒子交互循环,由此产生的复杂性是什么?