微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我的 if 函数没有从字符串中删除空格?它不能检测 C++ 中的空格输入吗?有没有办法从输入中删除空格

如何解决为什么我的 if 函数没有从字符串中删除空格?它不能检测 C++ 中的空格输入吗?有没有办法从输入中删除空格

问题 - 最近,Anton 发现了一套。该集合由小英文字母组成。安东小心地将集合中的所有字母写成一行,用逗号分隔。他还在行首添加一个开口弧形括号,并在行尾添加一个闭合弧形括号。

不幸的是,安东有时会忘记写一些信并重新写一遍。他让你数一数他的集合中不同字母的总数。

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

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

Code Forces 问题链接 - 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

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());
,

擦除后下一个字符的索引将保持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);
}
,

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

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

应该是:

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

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

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

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。