【问题标题】:How to delete a whole word from a string in C++? [duplicate]如何从 C++ 中的字符串中删除整个单词? [复制]
【发布时间】:2021-07-25 05:16:46
【问题描述】:

我的程序只删除了第一个单词“she”,其余的不受影响。如何删除?

int main()
{
    string mess = "she realizes she is her only hope and she stopped expecting help from others.";
    string word_to_delete = "she";

    int mess_len = (int)mess.length();
    int word_len = (int)word_to_delete.length();
        
    for(int i = 0; i < mess_len; i++)
    {
        for(int k = 0; k < word_len; k++)
        {
            if(mess[i] == word_to_delete[i])
            {
                mess[i] = 0;
            }
        }
    }
    cout << mess;
}

【问题讨论】:

  • 我认为最好的 2 个解决方案是由 2 个用户“rawrex”和“akash”创建的。它们简短、清晰、精确、快速和高效。两者都工作得很好,我已经测试过了。

标签: c++ string


【解决方案1】:

您应该考虑改用以下方法:

#include <iostream>
#include <string>

using namespace std;

int main() {
    string mess = "she realizes she is her only hope and she stopped expecting help from others.";
    string word_to_delete = "she";

    auto iter = mess.find(word_to_delete);
    // Iterate through the whole string searching for desired substrings
    while (iter != string::npos) {
        // Erase "she" plus a space after it (may require more fine tuning)
        mess.erase(iter, word_to_delete.length() + 1);
        // Advance further, look for "she" starting from iter
        iter = mess.find(word_to_delete, iter);
    }
    cout << mess << '\n';
} 

在这里,我们使用string's method find 来查找所需的子字符串,然后使用erase methodmess 中删除word_to_delete(加上一个空格)。

示例输出:

realizes is her only hope and stopped expecting help from others.

【讨论】:

  • 这是一个很好的解决方案:高效、快速、清晰和标准化。
【解决方案2】:

我觉得你也可以使用正则表达式来替换那个词。下面简单的代码sn-p供参考。

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

int main()
{

string mess = "she realizes she is her only hope and she stopped expecting help from others.";
string word_to_delete = "she";
mess = std::regex_replace(mess, regex(word_to_delete), "");
cout<<"\nUpdated mess: "<<mess;
return 0;
}

【讨论】:

  • 也是非常快速高效的解决方案。 :-)
【解决方案3】:

您在 for 循环中存在一些误解或错误的逻辑。此外,您必须在开始替换它们之前检查所有字符。

#include <bits/stdc++.h>
using namespace std;

int main() {
    string mess = "she realizes she is her only hope and she stopped expecting help from others.";
    // getline(cin, mess);
    string word_to_delete = "she";
    int mess_len = (int)mess.length();
    int word_len = (int)word_to_delete.length();
    int flag=-1;

    for(int i = 0; i < mess_len; i++)
    {
        for(int k = 0; k < word_len; k++)
        {
            if(mess[i+k] == word_to_delete[k])
            {
                flag=i;
            }
            else{
                flag=-1;
                break;
            }
        }
        if(flag!=-1){
            mess.erase(flag, word_len);
        }
    }
    cout << mess;
    return 0;
}

【讨论】:

    【解决方案4】:

    我尝试在下面提供一些代码示例以及一些解释,以表明我已修复它。

    问题出在你的嵌套循环中:

    ...
    
    for(int k = 0; k < word_len; k++)
    {
        if(mess[i] == word_to_delete[i])
        {
            mess[i] = 0;
        }
    }
    
    ...
    

    1.word_to_delete[]的索引不正确

    请记住,这个嵌套循环遍历数组“mess”的一个子部分,并完全遍历字符串“she”。 “她”存储在 word_to_delete 中。注意:您使用索引“i”(在外部循环中定义)来索引 word_to_delete。

    if(mess[i] == word_to_delete[i])
    

    'i' 将遍历值 0, 1, 2, 3, 4, 5, 6... 直到 'mess' 的最终索引。但是,word_to_delete 只有 3 个元素!相反,请使用您已经在嵌套循环中定义的索引“k”:

    if(mess[i] == word_to_delete[k])
    
    1. 整个 Word-To-Delete 不匹配

    我在刚才提到的修复之后测试并运行了你的程序,这是新的输出:

    aa raliz i r only op and toppd xpcting lp from otr.

    如您所见,您的程序只删除了 'mess' 中的所有字符,这些字符也在 'word_to_delete' 中!

    这是因为在这一步:

    if(mess[i] == word_to_delete[i])
    {
        mess[i] = 0;
    }
    

    您正在逐一检查字符,然后在字符匹配后立即更改它们。在将其更改为 0 之前,您必须检查 word_to_delete 中的所有字符是否与 mess[] 的一个小节匹配。

    1 解决方案是在嵌套循环之前声明一个新的 int 变量 'count'(初始化为 0)。然后,换行:

     mess[i] = 0;
    

    到:

    count += 1;
    

    对于 word_to_delete 进行的每个字符匹配,都会加 1。

    记住:如果每个字符都匹配“她”,您只想删除“混乱”的一个小节。因此,在嵌套循环之后,检查变量“count”以查看有多少匹配项。

    如果count 等于word_to_delete 的长度,那么字符串“she”已经被找到。否则,如果没有足够的匹配项,则 subsection 不等于“she”。

    这看起来像:

    if(count==word_len)
    {
        // iterate over subsection again and delete all characters,
        // this may require an additional for-loop
    }
    
    1. 嵌套循环中无偏移

    最后的修复很简单:

    在您的嵌套循环中,您不是在“偏移 i”。

    这里:

    for(int k = 0; k < word_len; k++)
    {
        // you are looping 'k' times, but you are always checking 'i'!
        if(mess[i] == word_to_delete[k])
        {
            count += 1;
        }
    }
    

    请注意,在 if 块中,您使用的是相同的值“i”。但是,当您遍历 'k' = 0, 1, 2 的值时,'i' 不会改变。

    相反,一种常见的编程模式是使用 'i' 作为您的基值,然后使用 k 的值与其偏移。

    记住:当我们遍历“混乱”时,我们想要检查一个小节。在您的示例中,我们要检查一个字符,然后检查接下来的 2 个字符。所以,在 mess[4],我们也想看到 mess[5],mess[6]。在 mess[27],我们还检查 mess[28]、mess[29]。

    我们可以通过将嵌套循环再次更改为:

    for(int k = 0; k < word_len; k++)
    {
        // now, since k = 0,1,2 in this loop,
        // if i = 7, then this loop will go through:
        // mess[7], mess[8], mess[9]
        if(mess[i+k] == word_to_delete[k])
        {
            count += 1;
        }
    }
    

    我们不需要更改 word_to_delete 的索引,因为 k 只经过 0、1、2,这已经是 word_to_delete 的正确索引。这将匹配 mess[] 的每个小节与 word_to_delete[]。

    实施这些更改后,最终输出似乎正确:

    意识到这是她唯一的希望,不再期待别人的帮助。

    注意:我注意到由于字符被删除的方式导致的潜在错误,但最好先了解代码中的其他问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-14
      相关资源
      最近更新 更多