Finding and changing repeated letters in a word - c++

I'm trying to create logic that goes through the word and tries to find if there are letters, that are used more than once. If a letter repeats, then change it to "1", if it's not then change it to "2". Example: Radar - 11211, Amazon - 121222, karate - 212122.
Specific problem is that if I use for(), each letter compares to the last one. Also I don't understand how can I check last letter by using for().
Last letter is always 2.
Here is my code:
#include <iostream>
#include <string>
using namespace std;
int main()
{ string word;
char bracket1('1');
char bracket2('2');
cout << "Write your word: ";
cin >> word;
for (int i = 0; i < word.length(); ++i)
{
char let1 = word[i];
char let2 = word[i+1];
if (let1 == let2)
{ word[i] = bracket1;}
else
{ word[i] = bracket2; }
} cout << word;
}
Example: test returns 1e22 instead of 1221

You have undefined behavior in your program when wrote word[i+1]; inside the for loop. This is because you're going out of bounds for the last value of i by using i+1.
One possible way to solve this would be to use std::map as shown below. In the program given std::tolower is used because you want capital and small letters to be treated the same.
#include <iostream>
#include <map>
#include <algorithm>
int main()
{
std::string word;
std::cout << "Write your word: ";
std::getline(std::cin, word);
//print out the word before replacing with 1 and 2
std::cout<<"Before transformation: "<<word<<std::endl;
std::map<char, int> charCount; //this map will keep count of the repeating characters
//iterate through each character in the input word and populate the map
for(char &c: word)
{
charCount[std::tolower(c)]++;//increment the value by 1
}
//replace the repeating characters by 1 and non-repeating by 2
for(char &c: word)
{
if(charCount.at(std::tolower(c)) > 1)
{
c = '1';
}
else
{
c = '2';
}
}
//print out the word after transformation
std::cout<<"After transformation: "<<word<<std::endl;
return 0;
}
The output of the program can be seen here.
Output for the input Amazon is:
Write your word: Amazon
Before transformation: Amazon
After transformation: 121222

Related

C++ I don't know how to find a word(eg.banana,sandwich) inside of a string(sentence) THE USER ENTERS the sentence and then write that word out

I've tried this but I'm stuck honestly.
I'm trying to find the first character, and then search for the ending of that substring (for eg. if the word is "sandwich" and it finds 's' that it figures out that its "sandwich") and then write out the word sandwich. And also I'm new to C++.
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s, word;
char a;
cout << "Enter the sentence that you desire: ";
getline(cin, s);
cout << "Enter the letter that you want: ";
cin >> a;
for (int i = 0; i < s.length; i++)
{
if (s[i] == a)
{
if (s[i] == '\0')
{
word = s;
cout << word;
}
}
}
return 0;
}
The request is a bit foggy but given also the code you posted, i think i got a heck of what you intend to do.
The easiest (yet not necessarily the most performing one) is to use a stringstream, more precisely an istringstream.
You basically build it with a string (the one you passed from keyboard) and then you use it as if it was your cin (it acts as a normalized istream).
At that point you can iterate each word of the sentence and check the first letter.
The first character of a string is either myString[0] or myString.front(). That is up to you.
the code should look like this :
#include <iostream> //cin/cout
#include <sstream> //istringstream
using namespace std ;
int main()
{
//first of all let's get our sentence AND the character you want
cout << "insert sentence here: " ;
string sentence ;
getline(cin, sentence) ;
cout << "insert the character here: " ;
char letter ;
cin >> letter ;
//then let's create an istringstream with said sentence
istringstream sentenceStream(sentence) ;
//let's then iterate over each word
string word ;
while(sentenceStream >> word)
{
//and see if the word starts with the letter we passed by keyboard
if(word.front() == letter)
{
cout << "the word \"" << word << "\" starts with '" << letter << "'\n" ;
}
}
return 0 ;
}
Just a couple of hints:
iostream includes string already, there is no need to re-include it.
[Edit] (as pointed out by whozcraig, this does not follow the standard. guards will "negate" the double inclusion anyway, so yes, including string is not a mistake. as specified in the comment, i'm yet to find an implementation of iostream that does not include string)[/Edit]
It is good practice not to call a variable 's', or 'a': use a name
that makes it recognizable.
You can find the end of a word with std::find_if:
#include <algorithm>
#include <string>
template <typename Is>
std::string find_word(Is& stream, char needle) {
auto const nonword = [](char c) {
if ('a' <= c && c <= 'z') return false;
if ('A' <= c && c <= 'Z') return false;
if (c == '-') return false;
return true;
};
for (std::string w; stream >> w;) {
if (w.size() && w[0] == needle) {
auto const last = std::find_if(std::begin(w),std::end(w),nonword);
return std::string(std::begin(w),last);
}
}
return "";
}
This takes any stream as argument, including std::cin, and can be invoked like this:
std::cout << find_word(std::cin,'w') << "\n";
It is important to specifically find the last character in each chunk handed you by the stream because the streams will only cut along whitespace by default. So if you enter a sentence:
Hello world!
You want the end of the word to be 'd', not '!'.

c++ count whitespaces between numbers (not strings)

So I have a program that takes in integers from user and puts them in a vector and displays them. however, I want to be able to show the total number of whitespaces between the numbers I put while inputting the numbers also.. I had a look online but couldn't find anything that would work for ints or chars.. I cant use strings or getline right now so idk what to do..
here is my code
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int a,count;
vector<int> numbers;
while(cin>>a)
{
numbers.push_back(a);
// count whitespaces??
}
for(int i=0;i<numbers.size();i++)
{
cout<<numbers[i]<<endl;
}
return 0;
}
so if the input is 1(space)2(space)(space)3(space)
i want to be able to calculate the total spaces in between so in this case count would be 4
Try getline():
string str;
getline(cin,str);
and then count whitespace in str:
int wc = 0;
for (auto c: str) wc += (c == ' ');
cout << wc << endl;

How to split a word into letters and put them into an unordered list/set?

I'm trying to build a simple anagram checker that compares two user inputs and prints whether the pair is an anagram or not.
Figured this would be a good way to go about it:
-Ask for user input1 and user input 2
-split input1 and input2 into individual letters
-put input1 letters into an unordered set and input2 letters into another unordered set.
-if (unordered set 1 == unordered set 2)
the pair is an anagram.
I'm having trouble figuring out how to split the inputs into individual letters and put each of them into their own unordered list/set.
#include <iostream>
int main()
{
std::cout << "Hey there! enter a pair of words and tell you if they're an anagram or not." << endl;
std::cout << "Enter first word: ";
std::string firstword{};
std::cin >> firstword;
std::cout << "Enter second word: ";
std::string secondword{};
std::cin >> secondword;
//split firstword into letters
//put letters into set1
//split secondword into letters
//put letters into set2
//if (set1 == set2)
//the pair is an anagram
return 0;
}
There are a few ways you can go about doing this. The way I chose to go about it is by first sorting each string, iterating through each of the strings and comparing the index of one string with the index of the other. In C++, each string is made up of characters, or chars, so you can access individual pieces of a string by their index.
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
string firstWord;
string secondWord;
bool isAnagram;
cout << "Hello! Enter the first word: ";
cin >> firstWord;
sort(firstWord.begin(), firstWord.end());
cout << "Enter the second word: ";
cin >> secondWord;
sort(secondWord.begin(), secondWord.end());
if(firstWord.length() == secondWord.length())
{
for(int i = 0; i < firstWord.length(); i++)
{
if(firstWord[i] == secondWord[i])
{
isAnagram = true;
}
else
{
isAnagram = false;
break;
}
}
}
else
{
isAnagram = false;
}
if(isAnagram)
{
cout << "It's an anagram!\n";
}
else
{
cout << "It's not an anagram.\n";
}
return 0;
}
A few side notes: I included using namespace std; at the top of my program. This is generally considered bad practice as it pulls the entire std namespace into the global namespace and can lead to name collisions. However, it works well for testing purposes. I also included the algorithm preprocessor directive, which contains the sort() function that I used to sort the strings.
If given words are anagrams then they must be a permutations of the same letter set.
#include <algorithm>
bool are_anagrams(const std::string& lhs, const std::string& rhs)
{
if (lhs.size() != rhs.size())
{
return false;
}
return std::is_permutation(lhs.cbegin(), lhs.cend(), rhs.cbegin());
}
The std::is_permutation is a free function from <algorithm> header that checks if provided iterators point to the permutations of the same set.
Refering to the question "how to split string into letters and put it into the set", you can use the std::set constructor to achive this goal.
std::string word = "foo";
auto start = word.cbegin();
auto end = word.cend();
std::set<char> letters{start, end};
The std::set constructors takes as a paramters a pair of iterators and uses them to construct the object.
You can iterate over a string exactly like over a vector. The elements are just the letters (as char).

How to iterate over the words of a sentence in C++?

My input is "Hello World" and my targeted output is "olleH dlroW".
So my idea is to get the sentence into a variable and then loop over the words in the sentence, reverse each of them and finally concatenate them into a new variable.
My question is: how to iterate over the words of the sentence?
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
string reverseword(string word)
{
string rword;
int size = word.length();
while (size >= 0)
{
rword+= word[size];
size = size -1;
}
return rword;
}
int main()
{
string sentence;
cout<<"Enter the word/sentence to be reversed: ";
cin >> sentence;
string rsentence;
// for every word in the sentence do
{
rword = reverseword(word);
rsentence = rsentence + " " + rword;
}
cout<<rword;
return 0;
}
Before you can iterate over words in a sentence, you need to read a sentence from input. This line
cin >> sentence;
reads the first word of a sentence, not the whole sentence. Use getline instead:
std::getline(std::cin, sentence);
With sentence in memory, you can iterate it word-by-word using istream_iterator as follows:
stringstream ss(sentence);
for (auto w = istream_iterator<string>(ss) ; w != istream_iterator<string>() ; w++) {
string &word = *w;
...
}
Demo.
Here is a solution that uses find and reverse to achieve the output:
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string sentence;
std::getline(std::cin, sentence);
std::cout << sentence << std::endl;
size_t cpos = 0;
size_t npos = 0;
while((npos = sentence.find(' ', cpos)) != std::string::npos)
{
std::reverse(sentence.begin() + cpos, sentence.begin() + npos);
cpos = npos + 1;
}
std::reverse(sentence.begin() + cpos, sentence.end());
std::cout << sentence << std::endl;
return 0;
}
Input:
this is a nice day
Output:
this is a nice day
siht si a ecin yad
for(short i=0;i<sentence.length();i++){
if(sentence[i] == ' '){
counter++;
i++;
}
words[counter] += sentence[i];
}
Note the above loop to split the sentence with space and store it to a string array, words[]
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
string reverseword(string word) // function to reverse a word
{
string rword;
int size = word.length();
while (size >= 0)
{
rword+= word[size];
size = size -1;
}
return rword;
}
int main()
{
string sentence;
cout << "Enter the word/sentence to be reversed: ";
std::getline(std::cin, sentence);
string rsentence;
string words[100];
string rword;
short counter = 0;
for(short i=0; i<sentence.length(); i++){ // looping till ' ' and adding each word to string array words
if(sentence[i] == ' '){
counter++;
i++;
}
words[counter] += sentence[i];
}
for(int i = 0; i <= counter; i++) // calling reverse function for each words
{
rword = reverseword(words[i]);
rsentence = rsentence + " " + rword; // concatenating reversed words
}
cout << rsentence; // show reversed word
return 0;
}
I have corrected the code. Hope this helps...!!
NB : You were using cin to read space seperated string that is not possible. You must use std::getline(std::cin, sentence) to read space separated strings.
You can also use std::reverse() to reverse a string
Please refer to Most elegant way to split a string?
to split your sentence into tokens(words)
then, iterate over the new list of words to perform any operation
An answers above gives a way to convert your input to words, i.e., cin >> sentence returns a "word" (so, just call it repeatedly).
However, this brings up the question of what is a "word". You would like to translate a computer construct - string of characters - into a more complex form - words. So, you must define what you mean when you want words. It can be as simple as "space" separated substrings or your string - then use the split function, or read your string a word at a time (cin >> word)
Or you may have more stringent requirements, like they can't include punctuation (like a period at the end of a sentence) or numbers. Then think about using Regex and word patterns (like, "\w+").
Or you may want "real" words like you would find in a dictionary. Then you need to take into account your locale, parse your input into chunks (using split, Regex, or something), and look up each chunk in a human language dictionary.
In other words, "word" parsing is only as simple or complex as your requirements are.
With Boost you could use the boost::split function:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <boost/algorithm/string.hpp>
int main()
{
std::string sentence = "Hello world";
std::vector<std::string> words;
boost::split(words, sentence, boost::is_any_of(" "));
std::string rsentence;
for (std::string word : words) // Iterate by value to keep the original data.
{
std::reverse(word.begin(), word.end());
rsentence += word + " "; // Add the separator again.
}
boost::trim(rsentence); // Remove the last space.
std::cout << rsentence << std::endl;
return 0;
}
This answer is my humble contribution to the fight against global warming.
#include <string>
#include <iostream>
#include <algorithm>
#include <cctype>
int main()
{
std::string sentence;
while (std::getline(std::cin, sentence))
{
auto ws = sentence.begin();
while (ws != sentence.end())
{
while (std::isspace(*ws)) ++ws;
auto we = ws;
while (we != sentence.end() && !std::isspace(*we)) ++we;
std::reverse(ws, we);
ws = we;
}
std::cout << sentence << "\n";
}
}
This assumes "word" is defined as "a sequence of non-whitespace characters". It is easy to substitute a different character class instead of "non-whitespace", e.g. for alphanumeric characters use std::isalnum. A definition that reflects the real-world notion of word as e.g. used in natural language sciences is far far beyond the scope of this answer.

Reading a sentence until ENTER key pressed using 2-D char array

I need to read a sentence word by word until "ENTER" key is pressed. I used a do..while loop to read words until ENTER key is pressed. Please suggest me some conditions for checking ENTER key press (or) others ways for reading similar input.
#include<iostream>
#include<string.h>
using namespace std;
int main(){
char a[100][20]={'\0'};
int i=0;
do{
cin>>a[i++];
} while( \\ Enter key is not pressed );
for(int j= 0 ; j < i ; j++)
cout<< a[j] << " ";
return 0;
}
The statement
cin>>a[i++];
blocks at the prompt already, until the ENTER key is pressed. Thus the solution is to read a single line at once (using std::getline()), and parse the words from it in a separate step.
As your question is tagged c++, you can do the following:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
int main() {
std::string sentence;
std::cout << "Enter a sentence please: "; std::cout.flush();
std::getline(std::cin,sentence);
std::istringstream iss(sentence);
std::vector<std::string> words;
std::string word;
while(iss >> word) {
words.push_back(word);
}
for(std::vector<std::string>::const_iterator it = words.begin();
it != words.end();
++it) {
std::cout << *it << ' ';
}
std::cout << std::endl; return 0;
}
See the fully working demo please.
As an improvement the current standard provides an even simpler syntax for the for() loop:
for(auto word : words) {
std::cout << word << ' ';
}
while (cin.peek() != '\n') {
cin >> a[i++];
}
First, I must say that πάντα ῥεῖ's solution is better.
But it might be to much for you if, you are beginner.
Besides, I think you want in 2-D array, not vectors.
#include<iostream>
#include<string.h>
using namespace std;
int main(){
/*
All of this is simplified.
For example there are no check if user entered word larger than 100 chars.
And that's not all, but because of simplicity, and easy of understanding....
*/
char a[100][20]={'\0'};
char c;
char buffer[2000];
int i=0, j, k = 0;
/*
Read in advance all to way to ENTER, because on ENTER key all data is flushed to our application.
Untill user hits ENTER other chars before it are buffered.
*/
cin.getline(buffer, 2000, '\n');
do {
c = buffer[k++]; //read one char from our local buffer
j = 0;
//while we don't hit word delimiter (space), we fill current word at possition i
// and of cource while we don't reach end of sentence.
while(c != ' ' && c != '\0'){
a[i][j++] = c; //place current char to matrix
c = buffer[k++]; //and get next one
}
i++; //end of word, go to next one
//if previous 'while' stopped because we reached end of sentence, then stop.
if(c == '\0'){
break;
}
}while(i < 20);
for(j= 0 ; j < i ; j++)
cout<< a[j] << " ";
cout << endl;
return 0;
}
How about using this as your while statement
while( getchar() != '\n' );
You'll need the <stdio.h> header file for this.
See the ideone link
You can try
cin.getline(buffer, 1000);