Reputation: 67
In the required code , I have to input a string and output that string after removing all occurences of a given word in that string.
Example: Say I wish to remove WUB
from the string.
Input1: WUBWUBABCWUB
Output1:ABC
Input2:WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB
Output2:WE ARE THE CHAMPIONS MY FRIEND
Here is my code:
#include <bits/stdc++.h>
using namespace std;
int main()
{
string in;
cin>>in; //input
int n=in.length();
int pos =in.find("WUB");
for(;pos!=-1;){
pos =in.find("WUB");
if(pos!=-1){ //manipulating string by erasing and inserting spaces between words
in.insert(pos+3," ");
in.erase(pos,pos+3);
}
}
if(in[0]==' ')
in.erase(in.begin());
if(in[n-1]==' ') //removing extra spaces
in.erase(in.end());
cout<<in;
}
It works for input 1, but for input 2 gives wrong output. Output2:WEETHEONSND
What is wrong here?
Upvotes: 0
Views: 119
Reputation: 376
You can create more efficient and neat code by using Regex to find the unwanted words, and then replace them with a space. Of course you will then have to use unique() to remove the double spaces.
Code
#include <iostream>
#include <regex>
bool BothAreSpaces(char lhs, char rhs)
{
return (lhs == rhs) && (lhs == ' ');
}
int main()
{
string s("WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB"); //Input string
regex e("(WUB)"); // Regex syntax to filtr unwanted string
string result; //Filtered string
regex_replace(std::back_inserter(result), s.begin(), s.end(), e, " "); //Replace unwanted word with space
string::iterator new_end = unique(result.begin(), result.end(), BothAreSpaces); //Find double spaces
result.erase(new_end, result.end()); //Remove double spaces
cout << result << endl;
}
Output
WE ARE THE CHAMPIONS MY FRIEND
Upvotes: 1
Reputation: 310990
Instead of two sequential calls of the function insert and erase you could use only one call of the function replace.
Moreover this call of member function earse
in.erase(pos,pos+3);
The second argument shall specify the number of characters that need to be erased.
Also it seems you need to remove all leading and trailing blanks instead of only one blank from the both sides.
if(in[0]==' ')
in.erase(in.begin());
if(in[n-1]==' ') //removing extra spaces
in.erase(in.end());
The program can look the following way
#include <iostream>
#include <string>
#include <limits>
int main()
{
while ( true )
{
std::cout << "Enter the source string (Enter - exit): ";
std::string s;
if ( not std::getline( std::cin, s ) or s.empty() ) break;
std::cout << "Enter the substring to remove: ";
std::string t;
std::cin >> t;
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
if ( not t.empty() )
{
for ( auto pos = s.find( t );
pos != std::string::npos;
pos = s.find( t, pos ) )
{
s.replace( pos, t.size(), 1, ' ' );
++pos;
}
}
s.erase( 0, s.find_first_not_of( " \t " ) );
auto pos = s.find_last_not_of( " \t " );
if ( pos != std::string::npos ) s.erase( ++pos );
std::cout << "The source string: \"" << s << "\"\n";
}
return 0;
}
Its output might look like
Enter the source string (Enter - exit): WUBWUBABCWUB
Enter the substring to remove: WUB
The source string: "ABC"
Enter the source string (Enter - exit): WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB
Enter the substring to remove: WUB
The source string: "WE ARE THE CHAMPIONS MY FRIEND"
Enter the source string (Enter - exit):
Upvotes: 1
Reputation: 30840
The overload of string::erase
you use is
basic_string& erase( size_type index = 0, size_type count = npos );
You are passing pos+3
as count, instead of just 3.
Upvotes: 2