Finding number of occurences of all characters in three strings in C++ - c++

I don't understand why this program is not working.
I need to find the number of occurrences of all characters in three strings by any method.
I used count method but if you guys can help me out with find function so it would be better.
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
string line[3];
int count[3];
cout << "Enter three lines of text...\n\n";
cin >> line[0];
cin >> line[1];
cin >> line[2];
int i;
for(char j='a'; j<=26; j++) {
for(i=0; i<3; i++)
count[i] = std::count(line[i].begin(), line[i].end(), j);
cout << "\n" << j << "\t" << ":" << "\t" << count[i];
}
system ("pause");
return 0;
}

26 is no letter, and (char)26 is normally less than 'a' - so your loop will not execute. Try char j='a';j<='z';j++

I would go for something like this:
#include <map>
#include <string>
#include <iostream>
int main()
{
// Given 3 strings...
std::string s1 = "Hello";
std::string s2 = "Cruel";
std::string s3 = "World";
//===============================================
// THESE 2 LINES ARE ALL YOU NEED FOR COUNTING
std::map<char, int> countMap;
for (char c : (s1 + s2 + s3)) { countMap[c]++; }
//===============================================
// Print the output. This is if you do not care about
// characters that do not appear at all.
for (auto const& e : countMap)
{
std::cout << e.first << ": " << e.second << std::endl;
}
// Print the output. This is if you DO care about
// characters that do not appear at all.
for (char c = ' '; c <= '~'; c++)
{
std::cout << c << ": " << countMap[c] << std::endl;
}
}

http://www.asciitable.com/
Lower case 'a' is 96. Which is less than 26 which is why your loop doesn't execute. Try:
for (char j = 'a'; j <= 'z'; j++)
This will only count the lower case characters. If you wanted the occurrence of lower and upper case you could do this:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
string line[3];
cout << "Enter three lines of text...\n\n";
cin >> line[0];
cin >> line[1];
cin >> line[2];
for(char j='a';j<='z';j++)
{
int upper_sum = 0;
int lower_sum = 0;
for(int i=0;i<3;i++)
{
lower_sum += std::count(line[i].begin(),line[i].end(),j);
upper_sum += std::count(line[i].begin(),line[i].end(),j - 32); //32 = 'a' - 'A'
}
cout<<"\n"<<j<<"\t"<<":"<<"\t"<<lower_sum;
cout<<"\n"<<(char)(j - 32)<<"\t"<<":"<<"\t"<<upper_sum;
}
return 0;
}

Here's a correct version of your program:
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
string line[3];
int count[3];
/*cout<<"Enter three lines of text...\n\n";
cin>>line[0];
cin>>line[1];
cin>>line[2];*/
line[0] = "aaaaabbbbbbbbbbb";
line[1] = "ccccccddddddddddd";
line[2] = "kkkkkkkkkkkkk";
int i;
for(char j='a';j<= 'z';j++) // You can loop through the alphabet, but you need to go 'a' to 'z' and not 26
{
for(i=0;i<3;i++)
{ // You were missing these braces, you need them if your loop contains multiple lines
count[i]= std::count(line[i].begin(),line[i].end(),j);
cout<<"\n"<<j<<"\t"<<":"<<"\t"<<count[i];
}
}
system ("pause");
return 0;
}
And here it is in action.

int i;
for(char j='a'; j<=26; j++) {
for(i=0; i<3; i++)
count[i] = std::count(line[i].begin(), line[i].end(), j);
cout << "\n" << j << "\t" << ":" << "\t" << count[i];
}
Your cout line isn't in the inner for loop.
After the inner loop finishes, i is 3. Then cout is called with count[i] which goes out of bounds on the array. Undefined behaviour, you're lucky if it crashes.
Your problem is the i. The place it's declared means it still exists and the cout line can reference it. If you move the declaration to the loop initialiser you'll find the next error:
for(int i=0; i<3; i++)
count[i] = std::count(line[i].begin(), line[i].end(), j);
cout << "\n" << j << "\t" << ":" << "\t" << count[i];
The last line won't compile as i goes out of scope at the end of the loop. I assume you were mistaken in thinking cout was part of the loop, partly due to the poor formatting of the code, and secondly because i was declared at a wider scope.
To correct this, create a block for the for loop by using { and }. This will keep the i in scope for all statements within the block, and repeat the statements for each iteration of the loop.
for(int i=0; i<3; i++) {
count[i] = std::count(line[i].begin(), line[i].end(), j);
cout << "\n" << j << "\t" << ":" << "\t" << count[i];
}

Related

ask the user if a sequence of two letters is in a random array of letters

The user inputs some desired length of a string of characters . then the program outputs a list of randomly generated characters. After which the user is prompted to input 2 characters (that either exist or does not exist whiten the list). the program will then output where the first character appears in the pair or say that the pair does not exist in the list.
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
int main()
{
int size, c;
char ltr1, ltr2;
cout << "How many letters do you want in your random sting? ";
cin >> size;
string str;
for (int i = 0; i < size; i++)
{
c = rand() % 26 + 'a';
str.push_back(c);
}
for (int i = 0; i < size; i++)
{
cout << str[i];
}
cout << endl << endl;
cout << "what pair of letters would you like to find?";
cin >> ltr1;
cin >> ltr2;
cout << endl;
for (int i = 0; i < size; i++)
{
if (char((str[i] == ltr1) && (str[i + 1] == ltr2)))
{
cout << "the pair is in the string starting at character number "
<< i << " in the string" << endl;
}
if (char((str[i] == ltr1) && (str[i + 1] != ltr2)))
{
cout << "the pair " << ltr1 << ltr2 << " is not in the string." << endl;
}
}
return 0;
}
the output is capable of determining weather or not the pair exist or not and will output the location however if you input a value greater than 25 it will run the final output multiple times.

How to move word in a circular motion in a string?

I have a string that contains X words (between each word there is a space) I have to move the words in a circular motion to the left according to the number that the user inserts. For example:
"hi my name is aviv and",
the user entered 2. "name is aviv and hi my" I'm looking for legality that repeats itself but I can not find.
Thanks for the guidance. Most importantly, I can not use built-in libraries
Update:
I see there are examples with libraries, I can not use any library.
So what I've done so far.
I wrote a function that gets a string and a number from the user, to move left.
Before sending the string to the function I try to calculate the number of characters I need to move.
My output is - "name is avivhi my"
Regarding the function:
When it gets a string without spaces it works great.
This is my code:
int main()
{
char str[] = "hi my name is aviv";
char str2[] = "hi my name is aviv";
int CountSpace = 0, CountWord = 0;
int Size = 18, flag = 0;
int MoveLeft, Index = 0;
for (int i = 0; str[i] != '\0'; i++)
{
if (str[i] == ' ')
{
CountSpace++;
}
}
CountWord = CountSpace + 1;//Understand how many words there are in a string.
cin >> MoveLeft;
if (MoveLeft >= CountWord)//
{
MoveLeft = (MoveLeft - ((MoveLeft / CountWord) * CountWord));//the size of movment;//To reduce the amount of moves if there is such a possibility
}
for (int i = Size - 1; i >= 0; i--)
{
if (str[i] == ' ')
{
flag++;
}
if (flag == MoveLeft)
{
Index = Size - 1 - (i + 1);//That's the amount of characters I have to move
break;
}
}
MoveLeft = Index;
//This code belongs to the function that accepts a string and the amount to move the characters
for (int i = 0; i < Size; i++)
{
if (i + MoveLeft < Size)
{
str[i] = str2[i + MoveLeft];
}
else
{
str[i] = str2[(i + MoveLeft) - Size];
}
}
cout << "Move Left: " << MoveLeft << endl << str << endl << str2 << endl;
return 0;
}
Here's a hint:
vector<string> words = Your_Code_To_Split_Input_Into_Words();
int count = words.size();
int shift = Your_Code_To_Read_Users_Input();
// print the sentence with the rotation specified by shift
for (int i = 0; i < count; i++)
{
int shifted_index = (i + shift) % count; // modulo math implements circular rotation
string spacing = (i == 0) ? "" : " "; // add a space before each word, except first word
cout << spacing << words[shifted_index];
}
cout << endl;
One possible answer, i highly recommend using vectors instead of regular arrays, it's easy and more dynamic, but i didn't use it because you said you can't use built-in libraries.
#include <iostream>
#include<string>
using namespace std;
int main() {
string a[10000];
int counter = 0;
string b = "hi my name is aviv and";
string temp = "";
int userNum = 2;
for(int i=0;i<b.length() ; i++){
if(b[i]!=' '){
temp+=b[i];
}
else if(b[i]==' ' && temp.length()){
a[counter]= temp;
temp = "";
counter++;
}
}
if(temp.length()){
a[counter] = temp;
}
for(int i=userNum;i<=counter+userNum;i++){
cout<<a[i%(counter+1)]<<endl;
}
}
If you can make use of std::rotate() from <algorithm>, this is much easy to do with that. Parse the words using std::stringstream and store to std::vector. Then apply the shif directly to the vector.
Sample Output: https://www.ideone.com/rSPhPR
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
int main()
{
std::vector<std::string> vec;
std::string str = "hi my name is aviv and";
std::string word;
std::stringstream sstr(str);
while(std::getline(sstr, word,' '))
vec.emplace_back(word);
int shift;
std::cout << "Enter the Shift: ";
std::cin >> shift;
std::rotate(vec.begin(), vec.begin() + shift, vec.end());
for(const auto& it: vec)
std::cout << it << " ";
return 0;
}
Here's a snippet :
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#define MaxWords 10
int main()
{
stringstream ss;
ss.str("hi my name is aviv and");
string str[MaxWords];
int i;
for (i =0; std::getline(ss, str[i],' ');i++ )
{
cout << str[i] << " ";
}
int n;
cout << "\nEnter pos to split : ";
cin >> n;
for (int j = n; j <= i; j++)
{
cout << str[j] << " ";
}
for (int j = 0; j < n; j++)
{
cout << str[j] << " ";
}
cout << endl;
return 0;
}
Output:

Display duplicate characters in a string

I wrote some code in C++ to display duplicate characters in a string, but if a character is repeated more than three times, the code prints the repeated character more than once.
For example if the string is aaaddbss, it should only print out ads but it prints aaads instead.
What am I doing wrong?
cout << " Please enter a string" << endl;
cin.getline(input, 100); // example input (ahmad wahidy) the output reads a a h a d instead of a h d
for (int i = 0;input[i]!='\0'; i++)
{
for (int j = i+1;input[j]!='\0'; j++)
{
if (input[i] == input[j])
{
cout << input[i] << " ";
}
}
}
cout << endl;
Instead of using your own custom methods, why not use a short and standard method?
Given an std::string input with the text, this will print the unique chars:
std::set<char> unique(input.begin(), input.end());
for (auto & c : unique)
{
std::cout << c << " ";
}
std::cout << std::endl;
You can use std::count and std::set:
#include <string>
#include <set>
#include <iostream>
using namespace std;
int main()
{
string s = "hellohowareyou";
set<char>the_set(s.begin(), s.end());
for (char i:the_set)
if (count(s.begin(), s.end(), i) > 1)
cout << i << endl;
}
Output:
e
h
l
o
If you are not allowed to use a map (and probably also not allowed to use a set), you could simply use an array of integers to count occurrences, with one entry for each possible char value. Note that a character - when taken as an ASCII value - can be directly used as an index for an array; however, to avoid negative indices, each character value should first be converted to an unsigned value.
#include <iostream>
#include <limits>
int main() {
const char* input = "aaaddbss";
int occurrences[UCHAR_MAX+1] = { 0 };
for (int i = 0;input[i] !='\0'; i++)
{
unsigned char c = input[i];
if (occurrences[c]==0) {
occurrences[c]++;
}
else if (occurrences[c]==1) {
occurrences[c]++;
cout << "duplicate: " << c << endl;
}
}cout << endl;
}

Anagram detection method c++. Problems converting string to ascii value

For anyone that might be able to help me figure this out. I am creating a method that will compare two strings and detect whether they are an anagram or not. An anagram is two strings that have the same letters, though they may be in a different order. For example "listen" and "iltsen" are anagrams.
I have decided to break the strings up into char arrays. I know that is working correctly because I tested it using cout on each array element. Next is where it goes wrong. I attempt to use the ASCII value of each char and add it to a variable for each array. This would mean that if the values match then they must be an anagram.
However for whatever unknown reason it is not working correctly. I am finding that it is reading index 0 twice for one array and not for the other. I am so confused beyond reason. I have absolutely no idea what this is occurring. I have tried multiple different solutions and had no luck finding out the problem. If anyone has any idea whats going on here I would greatly appreciate the help.
-Thanks!
#include "stdafx.h"
#include <iostream>
#include <string>
#include <math.h>
#include <iomanip>
#include <cctype>
#include <vector>
using namespace std;
bool isAnagram(string s1,string s2)
{
static char firstString[] = { 'c' };
static char secondString[] = { 'c' };
int size = s1.length();
static int count1 = 0;
static int count2 = 0;
cout << s1 << endl;
cout << s2 << endl;
if (s1.length() == s2.length())
{
for (int i = 0; i < size; i++)
{
firstString[i] = s1.at(i);
cout << i;
}
for (int i = 0; i < size; i++)
{
secondString[i] = s2.at(i);
cout << i;
}
cout << endl;
for (int i = 0; i < size; i++)
{
count1 = count1 + (int)firstString[i];
cout << "first" << i << ": " << firstString[i] << " = " << (int)firstString[i] << endl;
count2 = count2 + (int)secondString[i];
cout << "second" << i << ": " << secondString[i] << " = " << (int)secondString[i] << endl;
}
cout << count1 << " and " << count2 << endl;
if (count1 == count2)
return true;
}
else
return false;
count1 = 0;
count2 = 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
static char end;
do
{
string s1;
string s2;
cout << "Please enter the first string: ";
cin >> s1;
cout << endl << "Please enter the second string: ";
cin >> s2;
bool result = isAnagram(s1, s2);
static string resultString;
if (result == true)
resultString = "True";
else
resultString = "False";
cout << endl << "Anagram test result: " << resultString << endl;
cout << endl << "enter E for end or any other key to run again: ";
cin >> end;
cout << "----------------------------------------" << endl;
} while (end != 'e' && end != 'E');
return 0;
}
It's not useful to use static variables in your case, without them you wouldn't need the last 2 lines of isAnagram.
It's also useless to store both strings in char arrays because you can use them directly in your 3rd loop(also you are overflowing your buffer which has a size of 1)
for (int i = 0; i < size; i++)
{
std::cout << count1 << " ";
count1 = count1 + (int)s1.at(i);
cout << "first" << i << ": " << s1.at(i) << " = " << (int)s1.at(i) << endl;
count2 = count2 + (int)s2.at(i);
cout << "second" << i << ": " << s2.at(i) << " = " << (int)s2.at(i) << endl;
}
Also you can't say that 2 strings do contain the same letters by comparing the sum of their ASCII values, thats like saying 3 + 4 is the same as 2 + 5 because both give 7.
You could create an array of 52 ints, each element is a counter for its own letter, then you could loop over both strings with one loop where each letter of the first string is incrementing its element in the array and the second strings letters are decrementing elements.
if (s1.length() != s2.length())
return false;
std::vector<int> counts(52);
for (unsigned int i = 0; i < s1.length(); ++i)
{
++counts[s1[i] - (s1[i] < 91 ? 65 : 71)];
--counts[s2[i] - (s2[i] < 91 ? 65 : 71)];
}
be sure that the array is initialized to 0.
At the end you need to loop over the array, if one of the elements is not 0 it's not an anagram, else return true.
for (unsigned int i = 0; i < 52; ++i)
if (counts[i] != 0)
return false;
return true;

printing a char array backwards c++ using loops

i am trying to print an array of unknown length backwards so wrote that the loop should start at the terminator and go to the first letter printing each letter but it keeps printing only the first
#include <iostream>
using namespace std;
int main()
{
char word[10];
int i;
cout << "Enter a word: " ;
cin >> word;
for ( word[i]= '\0'; word[1] <0; word[i] --)
{
cout << word[i] << endl;
}
return 0;
}
You can print you C-style string backwards whith this one-liner:
reverse_copy(word,word+strlen(word),ostream_iterator<char>(cout));
Also please consider using std::string:
string word;
cin >> word;
copy(word.rbegin(),word.rend(),ostream_iterator<char>(cout));
You will need to #include the following headers for the above examples to work:
<algorithm>, <iostream>, <iterator>, <string> and <cstring>
Replace your loop it does nothing:
for (i= strlen(word); i >=0; i--)
{
cout << word[i] << endl; //endl is optional
}
Also for in case of long strings you may have to increase size of char array or its better to use
string word;
for (i= word.size(); i >=0; i--)
{
cout << word[i] << endl; //endl is optional
}
Here is a simple way to print a C-style string backwards.
for (size_t i = 0, i_end = std::strlen(word); i != i_end; ++i)
{
std::cout << word[i_end - i - 1];
}
std::cout << "\n";
Note that I save the result of strlen so that it is not called every time.
To get the result you want, you might want to use this code...
char word[10];
int sz;
do {
cout << "Enter a word: ";
cin >> word;
sz = strlen(word);
} while (sz > 10);
for (int i = sz; i >= 0; i--)
{
cout << word[i];
}