【问题标题】:Why is my if function not erasing blank space from a string? Can it not detect blank space inputs in c++? Is there a method to remove space from input为什么我的 if 函数没有从字符串中删除空格?它不能检测 C++ 中的空格输入吗?有没有办法从输入中删除空间
【发布时间】:2021-03-25 11:26:08
【问题描述】:

问题 - 最近,Anton 找到了一套。该集由小英文字母组成。安东小心翼翼地把集合中的所有字母写成一行,用逗号隔开。他还在行首添加了一个左曲括号,在行尾添加了一个右曲括号。

不幸的是,安东有时会忘记写一些信,然后再写一遍。他要求你数一数他的集合中不同字母的总数。

输入 - 第一行和单行包含一组字母。线的长度不超过 1000。保证该线从一个开口弧形括号开始,以一个闭合弧形括号结束。在它们之间,列出了小英文字母,用逗号分隔。每个逗号后跟一个空格。

输出 - 打印一个数字——Anton 集合中不同字母的数量。

代码强制问题链接 - https://codeforces.com/problemset/problem/443/A

我的代码 -

int main(){
    string s;
    int count=0;
    getline(cin,s);
    for(int i=0;i<s.length();i++){
        if(s[i]==' ' || s[i]=='}' || s[i]=='{' || s[i]==','){
            s.erase(i,1);
        }
    }
    for(int i=0;i<s.length();i++){
        cout << s[i];
    }
    sort(s.begin(),s.end());
    for(int i=0;i<s.length();i++){
        if(s[i]==s[i+1]){
            count++;
        }
    }
    cout << endl << (s.length()-count);
}

问题是当我输出字符串时,它也会显示我不想要的空格。输入将包含空格,例如 - {a, b, c}。 if 函数不知何故无法从字符串中删除该空格,这可能是什么问题,我该如何解决?

【问题讨论】:

  • 想想你删除了索引i处的字符后下一个字符的索引是多少
  • 它将保持i (?)
  • 我很确定这已经被询问和回答了,但我找不到它:(
  • 我明白我的错误,我现在感觉很愚蠢@largest_prime_is_463035818
  • 没有理由感到愚蠢,这是每个人都必须至少犯一次的错误之一

标签: c++ string algorithm if-statement getline


【解决方案1】:

正如已经发现的那样,问题是在删除一个字符后,i 再次递增,跳过下一个字符。擦除后你不应该增加i

for(int i=0;i<s.length();){
    if(s[i]==' ' || s[i]=='}' || s[i]=='{' || s[i]==','){
        s.erase(i,1);
    } else {
        i++;
    }
}

但单独调用 erase() 的解决方案也是 O(N2),因为每次 erase 都必须向前移动所有剩余的字符。

考虑使用 erase-remove idiom 代替 O(N) 性能:

s.erase(std::remove_if(s.begin(), s.end(), [](char c) {
    return c == ' ' || c == '}' || c == '{' || c == ',';
}), s.end());

【讨论】:

    【解决方案2】:

    擦除后下一个字符的索引将保持i

    更新代码 -

    int main(){
        string s;
        int count=0;
        getline(cin,s);
        for(int i=0;i<s.length();i++){
            if(s[i]==' ' || s[i]=='}' || s[i]=='{' || s[i]==','){
                s.erase(i,1);
                i--;
            }
        }
        for(int i=0;i<s.length();i++){
            cout << s[i];
        }
        sort(s.begin(),s.end());
        for(int i=0;i<s.length();i++){
            if(s[i]==s[i+1]){
                count++;
            }
        }
        cout << endl << (s.length()-count);
    }
    

    【讨论】:

    • 小变化,但我宁愿跳过i++,只在不擦除时增加i,增加和减少一点点
    【解决方案3】:

    即使您删除了一个使其跳过一个字符的字符,您仍在增加i。正如其他人指出的那样,只有在不增加 i 时才增加 erase

    由于 C++20 可以使用 std::erase_if(std::basic_string) 函数代替:

    std::erase_if(
        s,
        [](char c) { return /* your condition */ ; }
    );
    

    【讨论】:

      【解决方案4】:

      执行此操作的 C++ 方法:

        for(int i=0;i<s.length();i++){
              if(s[i]==' ' || s[i]=='}' || s[i]=='{' || s[i]==','){
                  s.erase(i,1);
                  i--;
              }
      

      应该是:

       const std::string get_rid_of(" ,{}");
       s.erase(std::remove_if(s.begin(), s.end(), [=](char c)
               {
                   return get_rid_of.find(c) != std::string::npos;
               }), s.end());
      

      【讨论】:

        【解决方案5】:

        您选择的迭代器类型无效,它只会擦除整个字符串。
        试试这个:

        string::iterator itr;
        itr = s.begin(); 
        s.erase(itr); 
        

        【讨论】:

        • //s 是字符串。这将删除开头的字符。
        猜你喜欢
        • 2021-05-17
        • 2011-11-15
        • 2018-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-25
        • 2022-12-16
        • 1970-01-01
        相关资源
        最近更新 更多