#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void rmvdupli(string s)
{
if (s.length() == 1)
{
cout << s;
return;
}
char c = s.at(0);
if (((s.substr(1)).find(c)) >= 0)
cout << "";
else
cout << c;
rmvdupli(s.substr(1));
}
int main()
{
cout << "Enter the string " << endl;
string s;
cin >> s;
rmvdupli(s);
return 0;
}
Output
Enter the string
ababcdc
c
What is the problem with the code? It seems perfectly alright but answer is not coming!!
I modified your code with a bit of refactoring in order to fix the bugs and improve its readability and performance. I also added another overloaded function that is significantly faster and uses 0 heap allocations. It does the same thing though but in a far more optimized way.
Here:
#include <iostream>
#include <string>
#include <string_view>
// this is basically your function but is more efficient now
void removeDuplicateChars( const std::string& str )
{
if ( str.length( ) == 1 )
{
std::cout << str;
return;
}
const char firstChar = str[ 0 ];
const std::string&& restOfStr { str.substr( 1 ) };
if ( restOfStr.find( firstChar ) == std::string::npos )
{
std::cout << firstChar;
}
else
{
std::cout << "";
}
removeDuplicateChars( restOfStr );
}
// this one is far superior to the above one
void removeDuplicateChars( std::string_view&& strView )
{
if ( strView.length( ) == 1 )
{
std::cout << strView;
return;
}
const char firstChar = strView[ 0 ];
strView.remove_prefix( 1 );
if ( strView.find( firstChar ) == std::string_view::npos )
{
std::cout << firstChar;
}
else
{
std::cout << "";
}
removeDuplicateChars( std::move( strView ) );
}
int main( )
{
std::cout << "Enter the string: ";
std::string str;
std::cin >> str;
removeDuplicateChars( str ); // this calls the first overload
std::cout << '\n';
removeDuplicateChars( std::string_view( "ababcdc" ) ); // this calls the
// second overload
return 0;
}
Sample input/output:
Enter the string: ababcdc
abdc
abdc
I would highly recommend you to ditch the 1st overload and only use the 2nd one. Not only it's faster but also supports the types std::string, std::string_view, and C-style strings.
Here are some useful links to improve your knowledge:
std::string_view
std::string::substr
std::string::find
The below line:
if (((s.substr(1)).find(c)) >= 0)
should be changed to:
if (s.substr(1).find(c) != std::string::npos)
It basically means that c is found in s.substr(1).
find returns std::string::npos if the character is not found.
I have tried to solve this problem of yours.
What I have done is, I have replaced duplicate characters with whitespace.
if you want to remove whitespace you can find the code easily on internet.
C++ Code:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void RemoveDuplicateChar(string inputString)
{
if(inputString.length() == 1){
cout << inputString;
cout << "\nIt has only one character";
}else{
int stringLength = inputString.length();
cout<< "Original string: ";
cout << inputString;
cout << "\n";
for(int i =0 ; i<stringLength; i++){
for(int j = i+1; j< stringLength; j++){
if(inputString[i] == inputString[j]){
inputString[j] = ' ';
}else{
continue;
}
}
}
cout << "Duplicate character removed\n";
cout << "New String: ";
cout << inputString;
}
}
int main()
{
string input;
cout << "Enter a string with repeated characters: ";
cin >> input;
RemoveDuplicateChar(input);
return 0;
}
Output:
Enter a string with repeated characters: ababcdc
Original string: ababcdc
Duplicate characters removed
New String: ab cd
Related
im going to write a small program where the user types in a email adress and the code have to check if the email includes a #: ive just started programing and this is what ive come up with so far:
#include <iostream>
#include <string>
using namespace std;
int main() {
cout << "Skriv in en Epostadress: \n";
string adress;
cin >> adress;
if (adress == "#"){
cout << "Giltig!";
}
else {
cout << "Ogiltig!";
}
return 0;
}
Use member function find of the class std::string.
if ( adress.find( '#' ) != std::string::npos ){
cout << "Giltig!";
}
else {
cout << "Ogiltig!";
}
Here is a demonstrative program.
#include <iostream>
#include <string>
int main()
{
std::string address( "Harald.Scherr#gmail.com" );
std::string::size_type pos;
if ( ( pos = address.find( '#' ) ) != std::string::npos )
{
std::cout << "The character '#' is found at position " << pos << '\n';
}
else
{
std::cout << "The character '#' is not found\n";
}
return 0;
}
Its output is
The character '#' is found at position 13
maybe your problem is that you are comparing the whole string with "#" which was never the case for you,
however if you are tring to find the "#" in the input string then you will need to look for it as a char using for loop, you are very lucky however that you can go over the string as an array of characters in c++
try this maybe:
for(int i=0; i<adress.size(); i++){
if (adress[i] == '#'){
cout << "Giltig!" << endl;
return 0;
}
}
cout << "Ogiltig!" << endl;
return 0;
I have a trouble with a search through a string, if I enter a word with only letters, it's work as needs, I though, the code works, but when I add a number in work, the code work also, the question that, is possible to accept only if my var contains only letters, and if it will find a number or symbol, to go at begining of code?
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
label:
string var1 = "";
cout << "Enter a word: ";
cin >> var1;
for (int i = 0; i < var1.size (); i++)
{
int uppercaseCHar = toupper (var1[i]);
if (uppercaseCHar < 'A' || uppercaseCHar > 'Z')
{
goto endloop;
cout << endl;
} else
goto label;
cout << endl;
}
endloop:
cout << "Yout word contains only letters";
}
Output:
Enter a word: work
Enter a word: wro1
Enter a word: 123
Yout word contains only letters
Here is a solution that uses std::all_of:
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>
int main()
{
bool isAllLetters = false;
do
{
std::string var1;
std::cout << "Enter a word: ";
std::cin >> var1;
// check if all characters are letters
isAllLetters = std::all_of(var1.begin(), var1.end(), [](char ch)
{ return std::isalpha(static_cast<unsigned char>(ch));});
if ( isAllLetters )
std::cout << "Your word contains only letters\n";
else
std::cout << "Your word contains stuff other than letters\n"
} while ( !isAllLetters );
}
Simple and efficient (C++17):
#include <algorithm>
#include <cctype>
#include <string_view>
bool all_of_alpha(std::string_view s)
{
return std::all_of(s.begin(), s.end(), [](unsigned char c) { return std::isalpha(c); });
}
Avoid using goto as it will complicate debugging code in larger program , here's another way :
int main()
{
while (true) {
bool flag = false; // to check for numeric entry
string var1; // not req to initialize
cout << "Enter a word (press exit to end): ";
cin >> var1;
for (int i = 0; i < var1.size(); i++)
{
int uppercaseCHar = toupper(var1[i]);
if (!std::isalpha(uppercaseCHar))
{
flag = true;
break;
}
}
if (var1.compare("exit") == 0) break;
if (flag) {
cout << "Your word contains number";
cout << endl;
}
else
{
cout << "Your word contains only alphabets";
cout << endl;
}
}
}
You can also use regular expressions which will simplify the code further.
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main () {
regex reg_obj("^[A-Z]+$");
string var;
start_label:
cout << "Enter a word: ";
getline(cin, var);
if(regex_match(var, reg_obj))
goto endlabel;
else goto start_label;
endlabel:
cout << "your word contains only letters\n";
return 0;
};
Allow me to offer a more modern idiomatic version and assuming you only care about detecting alphabetic characters in the ASCII character set.
#include <iostream>
#include <algorithm>
#include <string>
int main()
{
std::string a = "abcdefgh";
std::string b = "abcd3fgh";
std::string c = "abcdefg0";
auto is_alpha = [](unsigned char c){ return std::isalpha(c); };
bool aContainsAlphas = std::all_of(a.begin(), a.end(), is_alpha);
bool bContainsAlphas = std::all_of(b.begin(), b.end(), is_alpha);
bool cContainsAlphas = std::all_of(c.begin(), c.end(), is_alpha);
std::cout << std::boolalpha;
std::cout << "A: " << aContainsAlphas << '\n'; // true
std::cout << "B: " << bContainsAlphas << '\n'; // false
std::cout << "C: " << cContainsAlphas << '\n'; // false
}
This defines a lambda which is passed as an argument to std::all_of, which uses it to test each character:
auto is_alpha = [](unsigned char c){ return std::isalpha(c); };
This invokes is_alpha on each element between a.begin() and a.end(). If the end is reached without any mismatch for is_alpha, then true is returned.
bool aContainsAlphas = std::all_of(a.begin(), a.end(), is_alpha) != a.end();
I initialized an array of characters, to put all uppercase and lowercase alphabets.
#include <iostream>
using namespace std;
int main () {
char c;
int cnt = 0;
cout << "Enter 0 to view the results " << endl;
char arr[52] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
while (1) {
for (int i = 0; i < 100000000; i++)
{
cin >> c;
if (c == arr[i]){
cnt++;
}
else if (c == '0'){
break;
}
else{
cout << "Please enter only characters!" << endl;
}
}
if (c == '0')
break;
}
cout << cnt << endl;
return 0;
}
I know that this code is inefficient.
How to write this code without break;?
If there's a better way to do that without using array, please mention it.
OP's question is very unclear but what I have understood from the comments is OP trying to find a simpler/similar way of counting someone's input for lowercase/upperCase alphabets and keep doing so until the user enters in a 0, I looked online and i found a better way and did some adjustments, it is pretty straight forward, here it is below.
#include <algorithm>
#include <iostream>
#include <cctype>
#include <string>
using namespace std;
int main()
{
string s = "TEST";
while(s != "0"){
cout << " Enter text: ";
getline(cin, s);
size_t count_alpha = count_if(s.begin(), s.end(),
[](unsigned char ch) { return isalpha(ch); });
cout << "Alphabets: " << ( count_alpha)<<endl ;
}
}
The loop in the program seems to execute at least once, even if there are no occurences of the substring. Why is this?
#include <iostream>
#include <string>
using namespace std;
int countSubstrings(const string& original_string, const string& substr) {
int number_of_ocurrences = 0;
int i = 0;
for (i = original_string.find(original_string, 0); i != string::npos;
i = original_string.find(substr, i)) {
number_of_ocurrences++;
i++;
}
return number_of_ocurrences;
}
int main() {
string input;
while (1) {
cout << "Enter a a line of text: ";
getline(cin, input, '\n');
cout << '\n';
cout << "Number of ocurrences of the word needle: ";
cout << countSubstrings(input, "needle") << '\n';
}
}
Initially when you set i in your for loop you have
original_string.find(original_string, 0)
So you are searching the string for itself which it will find. I believe you meant to have
original_string.find(substr, 0)
need to create a word matcher which counts how many times a specific word is mentioned in a text file. here is what i have done so far and am not sure what iv done wrong. 1 text file contains a long paragraph the other just contains a few words. I need to compare both text files e.g. the word "and" is in the short text file. need to compare this with the long paragraph and see how many time this words appears and then have a report at the end of the program which displays this.
E.g and - 6tmes, but - 0times, it - 23times.
^^ something like this. not sure how to start making this
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream infile("text1.txt");
if(!infile)
{
cout << "Error";
}
string words[250];
int counter = 0;
while (!infile.eof() )
{
infile >> words[counter];
counter++;
}
ifstream infile2("banned.txt");
if(!infile2)
{
cout << "Error";
}
string bannedwords[250];
counter = 0;
while (!infile2.eof() )
{
infile2 >> words[counter];
counter++;
}
int eatcount= 0;
int orcount = 0;
int hellocount = 0;
int number;
for(int i=0; i<200; i++)
{
for(int j = 0; j < 8; j++)
{
if ( words[i] == bannedwords[j])
{
cout << words[i] << " ";
if (words[i]=="eat")
{
eatcount++;
}
else if (words[i] == "or")
{
orcount++;
}
else if (words[i]== "hello")
{
hellocount++;
}
}
}
}
cout << endl;
cout<< "eat was found "<<eatcount<<" times";
cout << endl;
cout<< "or was found "<<orcount<<" times";
cout << endl;
cout<< "hello was found "<<hellocount<<" times";
system("pause");
}
Why not use a std::multiset?
ifstream infile("text1.txt");
if(!infile)
{
cout << "Error";
}
std::multiset<string> words;
string tmp;
while (!infile.eof() )
{
infile >> tmp;
words.insert(tmp);
}
Then also use a map for the banned words:
ifstream infile2("banned.txt");
if(!infile2)
{
cout << "Error";
}
std::map<string, int> banned;
string tmp;
while (!infile2.eof() )
{
infile2 >> tmp;
banned.insert(tmp);
}
Then you can use std::multiset::count(string) to find the words without all the extra looping. You would only need one loop to go through your banned words list. e.g:
std::map<string, int>::iterator bannedwordIter = bannedwords.begin();
for( ; bannedwordIter != bannedwords.end(); ++bannedwordIter )
{
bannedwordIter->second = words.count(bannedwordIter->first);
// you could print here as you process, or have another loop that prints it all after you finish
cout << bannedwordIter->first << " - " << bannedwordIter->second << " times." << endl;
}
A minimal way would be to use regular expressions, like so
#include <iostream>
#include <fstream>
#include <string>
#include <regex>
using namespace std;
unsigned countMatches(std::istream &is, std::string const &word)
{
string text;
unsigned count(0);
std::regex const expression(word);
while (getline(is, text)) {
count += distance(sregex_iterator(
text.begin(), text.end(), expression), sregex_iterator());
}
return count;
}
so you just pass it the input stream (in your case an input file stream) and it counts the occurences of the word specified after creating a regular expression that matches that word
int main()
{
ifstream ifs;
ifs.open("example_text_file.txt");
cout << countMatches(ifs, "word_you_want_to_search_for") << endl;
return 0;
}