1

My program only deletes the first word "she" but the rest isn't affected. How can I delete it?

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;
}
cigien
  • 57,834
  • 11
  • 73
  • 112
  • I think the best 2 solutions are created by 2 users "rawrex" and "akash". Theirs are short, clear, precise, fast, and efficient. Both work well as I have tested. – Job_September_2020 Jul 25 '21 at 09:03

4 Answers4

2

You should consider looking toward the following approach instead:

#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';
} 

Here, we use string's method find to look for a desired substring, then we use erase method to delete the word_to_delete (plus a space) from the mess.

Example output:

realizes is her only hope and stopped expecting help from others.
rawrex
  • 4,044
  • 2
  • 8
  • 24
1

I feel you can use regular expression also to replace that word with something. Simple code snippet below for reference.

#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;
}
Akash
  • 36
  • 5
0

There was some misunderstanding or wrong logic by you inside for loop. Also you have to check all char before starting to replace them.

#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;
}
Suryansh Singh
  • 1,123
  • 7
  • 15
0

I've tried providing some code examples below, along with some explanations, to show I fixed it.

The issues are in your nested loop:

...

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

...

1.Incorrect Index to word_to_delete[]

Remember that this nested loop iterates through a subsection of the array 'mess', and iterates completely through the string "she". "she" is stored in word_to_delete. Notice: you use the index 'i' (defined in the outer loop) to index to word_to_delete.

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

'i' will go through the values 0, 1, 2, 3, 4, 5, 6... until the final index of 'mess'. But, word_to_delete has only 3 elements! Instead, use the index 'k' that you've already defined in the nested loop:

if(mess[i] == word_to_delete[k])
  1. Entire Word-To-Delete is not matched

I tested and ran your program after the fix I just mentioned, here was the new output:

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

As you can see, your program only deletes all the characters in 'mess' that's also in 'word_to_delete'!

This is because in this step:

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

you are checking the characters 1-by-1, and then changing them as soon as the characters match. You must check that ALL characters in word_to_delete matches a subsection of mess[], before changing it to 0.

1 solution is to declare a new int variable 'count' (initialized to 0) before the nested loop. Then, change the line:

 mess[i] = 0;

to:

count += 1;

Which counts up 1 for each character match that word_to_delete makes.

Remember: you only want to delete a subsection of 'mess' if each character matches 'she'. So, after the nested loop, check the variable 'count' to see how many matches there were.

If count equals the length of word_to_delete, then the string "she" has been found. Else, if there were not enough matches, the subsection is not equal to "she".

This will look something like:

if(count==word_len)
{
    // iterate over subsection again and delete all characters,
    // this may require an additional for-loop
}
  1. No Offset in Nested Loop

The final fix is a simple one:

In your nested loop, you are not 'offsetting i'.

Here:

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;
    }
}

notice that, in the if block, you are using the same value 'i'. But, 'i' does not change when you iterate through values of 'k' = 0, 1, 2.

Instead, a common programming pattern is to use 'i' as your base value, and then the values of k to offset from it.

Remember: when we iterate through 'mess', we want to check a subsection. In your example, we want to check a character, and then the next 2 characters. So, at mess[4], we also want to see mess[5], mess[6]. At mess[27], we also check mess[28], mess[29].

We can do this by changing your nested loop again to:

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;
    }
}

We don't need to change the index for word_to_delete, because k only goes through 0,1,2, which are already the correct indices for word_to_delete. This will match every subsection of mess[] against word_to_delete[].

After implementing these changes, the final output seems correct:

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

Note: I've noticed a potential bug due to how the character is deleted, but it's better for you to understand the other problems in your code first.

Aiman
  • 59
  • 1
  • 4