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

Posted

技术标签:

【中文标题】为啥我的 if 函数没有从字符串中删除空格?它不能检测 C++ 中的空格输入吗?有没有办法从输入中删除空间【英文标题】: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 没有理由感到愚蠢,这是每个人都必须至少犯一次的错误之一 【参考方案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 是字符串。这将删除开头的字符。

以上是关于为啥我的 if 函数没有从字符串中删除空格?它不能检测 C++ 中的空格输入吗?有没有办法从输入中删除空间的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能删除这个表格?

为啥不能用scanf读入一个含有空格的字符串

excel 删除字段的前后空格

为啥从sqlserver里读出的字符串末尾含空格?

从找到空格和标点符号的数组中删除字符[重复]

为啥我不能删除字符串的数字字符?