【问题标题】:Replacing a substring with a space character用空格字符替换子字符串
【发布时间】:2020-12-19 08:29:57
【问题描述】:

我得到一个字符串,我必须从中删除一个子字符串。即WUB,并将其替换为空格字符。

ÁRE 和 'THE' 之间有 2 个WUB。所以 if 语句中的第一个条件是不打印两个空格,而是在执行代码时打印两个空格。

Input:  WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB
Output: WE ARE THE CHAMPIONS MY FRIEND 

到目前为止,这是我的代码:

#include <iostream>

using namespace std;

int main()
{
    const string check = "WUB";
    string s, p;
    int ct = 0;
    cin >> s;

    for (int i = 0; i < s.size(); i++)
    {
        if (s[i] == 'W' && s[i+1] == 'U' && s[i+2] == 'B')
        {
            i += 2;
            if (p[ct] == '32' || p.empty())
            {
                continue;
            }
            else
            {
                p += ' ';
                ct++;
            }
        }
        else
        {
            p += s[i];
            ct++;
        }
    }

    cout << p;
    return 0;
}

为什么第一个 if 语句从未执行?

【问题讨论】:

  • 是什么让您认为编译器正在跳过它?调试代码时看到了什么?
  • s[i+1]s[i+2] 将在 i == s.size() - 1i == s.size() - 2 (循环的最后一次和倒数第二次迭代)时越界。
  • '32' 是一个多字符常量,它们的工作方式是特定于实现的。你的意思是p[ct] == 32整数常量32),还是p[ct] == ' '检查单个空格(或者std::isspace(p[ct])检查任何空格)?
  • 顺便说一句,由于p 开始是空的,那么p[ct] 也有可能超出范围。实际上,由于您以递增的ct 锁步追加字符,因此ct 将始终等于p.size(),因此ct始终超出范围。

标签: c++ string if-statement stdstring


【解决方案1】:

有两件事会破坏你的代码:

  1. 您正在执行这样的 for 循环 int i=0;i&lt;s.size() 但读取 (s[i]=='W' &amp;&amp; s[i+1]=='U' &amp;&amp; s[i+2]=='B')
  2. 在这里:if(p[ct]=='32') 你的意思是肯定 if(p[ct]==32) 或 if(p[ct]==' ')

【讨论】:

    【解决方案2】:

    这个条件

    if(p[ct]=='32')
    

    应该读

    if(p[ct]==32)
    

    if(p[ct]==' ')
    

    即与空格字符的数值或空格字符本身进行比较。

    此外,当您的i 增长到接近字符串的长度时,子表达式s[i+1]s[i+2] 可能会到达字符串的非退出字符。您应该使用i&lt;s.length()-2 条件继续循环。

    编辑

    要获得完整的解决方案,您需要完全了解要解决的问题。问题陈述有点模糊:

    从(给定字符串)中删除子字符串("WUB")。并在其位置放置一个空格如果需要

    您考虑了最后一个条件,但还不够深入。 '如果需要'是什么意思?如果结果字符串为空您已经向其附加了一个空格(当您遇到第二个连续的WUB),则不需要替换。如果您在WUB,也没有必要,但它之后没有更多内容 - 除了可能是另一个WUBs...

    因此,当您找到"WUB" 子字符串时,现在决定是否需要空格还为时过早。当您发现非WUB 文本以下一些WUB(或WUBs)并且有一些文本之前那些@时,您知道您需要一个空格987654336@(s).

    【讨论】:

    • 或者你可以使用if(std::isspace(p[ct]))
    • 我处理了越界条件,但仍然忽略了第一个 if 语句。
    • @logan007 你也修复了 this 错误吗?你怎么知道它被忽略了?修复这两个错误后,我无法重现您的问题。
    • @churill 如果你看到 ÁRE 和 'THE' 之间有 2 个 WUB。所以我的 if 语句是为了不打印两个空格,但即使在修复了错误之后,您也会注意到实际上正在打印两个空格。
    • @logan007 是的,您可能希望编辑您的问题以更清楚地了解您面临的问题。如果您想知道问题出在哪里,请参阅一些程序员老兄的评论。
    【解决方案3】:

    这里实际上存在三个错误,因此可能值得在一个答案中总结它们:

    1. 第一个条件:

      if (s[i] == 'W' && s[i+1] == 'U' && s[i+2] == 'B')
      

      超出最后两个字符的范围。一种解决方法是先检查长度:

      if(i < s.length() - 2 && s[i] == 'W' && s[i+1] == 'U' && s[i+2] == 'B')
      
    2. 里面有一个multicharacter-literal

      if (p[ct] == '32' || p.empty())  
      

      请改用' '32std::isspace。 IMO 最后一个是最好的。

    3. 同样的情况

      p[ct] == '32' 
      

      总是超出范围:ct 等于 p.length()。 (感谢在 cmets 中提到这一点的一些程序员老兄!)变量 ct 也是多余的,因为 std::string 知道它的长度。我建议使用std::string::back() 访问最后一个字符并将条件重新排序:

      if (p.empty() || std::isspace(p.back()))  
      

    【讨论】:

      【解决方案4】:

      这个程序的算法是正确的。

      但是,有一些问题..

      1. for 循环超出索引。解决此问题的一种方法是减去大小 -3。像这样。

        for (int i=0; i

      2. 我不建议使用其他变量作为计数器,如 ct。在这种情况下,ct 可以通过在 for 循环中使用 p[ct] 来达到索引超出范围的错误。 创建一个字符串并使用 append() 函数将是一个更好的解决方案。在这种情况下,我们遍历字符串中的每个字符,如果我们找到“WUB”,那么我们附加一个“”。否则,我们追加字符。

      3. 我强烈建议使用 C++ 中的 substring() 编写第一个 if() 语句。 这使代码更易于阅读。

      Substring 创建并返回一个从特定位置开始到结束位置的新字符串。这是语法

      语法:substr(startingIndex,endingIndex); endingIndex 是排他性的

      #include <string>
      #include <iostream>
      
      int main() {
         string s, p;
         cin >> s;
         for(int i=0;i<s.size()-3;i++) {
            if (s.substr(i, i+3) == "WUB") {
               p.append(" ");
            } else {
               p.append(s.substr(i,i+1));
               i++;
               continue;
            }
            i+=3;
         }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-09
        • 1970-01-01
        • 2018-09-19
        • 2012-04-28
        • 2013-05-09
        • 1970-01-01
        • 1970-01-01
        • 2021-05-11
        相关资源
        最近更新 更多