Character Counter in C++? - c++

I'm trying to find a way to display all the characters in a string and the number of times they occur.
This is what I have so far:
//Any unused includes are part of the default code
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <string>
using namespace std;
int main()
{
string st = "";
cout << "Input a sentence: " << endl;
getline(cin, st);
int index = 0;
int index2 = 0;
int counters[26] = {0};
for(int i = 0; i < st.length(); i++)
{
int counter = 0;
index = st.find(st[i],0);
for(int j = 0; j < st.length(); j++)
{
index2 = st.find(st[j]);
if(index == index2)
{
counter++;
}
}
cout << st[i] << ": " << counter << endl;
}
//cout << st[i] <<": " << counters[st[i] - 'a'] << endl;
return 0;
}
and I return this:
Input a sentence:
hello
h: 1
e: 1
l: 2
l: 2
o: 1
so I kind of have something but I can't figure out how to make the letters not repeat more than once. I know that I need to store them in an array but it's out of my ken.

You were very close, nice try! I liked the approach with the counters array, where every cell would represent the frequency of a letter in the given string.
So, just go and update this array, as this answer implies How to get character's position in alphabet in C language?, without the plus one they mention there, since you want the index of the letter in your array. In other words, for 'a', you need 0, 'b', you need 1 and so on.
Then, in the printing phase, just use the above link's suggestion in the reverse way. When you print the i-th non-zero element of counters, print the i-th element of the element, which will reveal the letter in question.
Putting all together, you get:
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <string>
using namespace std;
int main()
{
string st = "";
cout << "Input a sentence: " << endl;
getline(cin, st);
int index = 0;
int index2 = 0;
int counters[26] = {0};
for(size_t i = 0; i < st.length(); i++)
{
int counter = 0;
index = st.find(st[i],0);
for(size_t j = 0; j < st.length(); j++)
{
index2 = st.find(st[j]);
if(index == index2)
{
counter++;
}
}
counters[st[i] - 'a'] = counter; // update 'counters' array
}
for(int i = 0; i < 26; ++i)
if(counters[i] != 0) // print non-zero counters
cout << (char)(i + 'a') << ": " << counters[i] << endl;
return 0;
}
Output:
e: 1
h: 1
l: 2
o: 1

I would do something like this:
#include <iostream>
#include <map>
#include <string>
int main()
{
std::string st;
std::cout << "Input a sentence: " << std::endl;
std::getline(std::cin, st);
std::map<char, int> m;
for (const char c : st)
++m[c];
for (const std::pair<char, int>& me : m)
std::cout << me.first << ": " << me.second << std::endl;
}

lechuga2000 beat me to the post, but this is my suggestion:
#include <iostream>
#include <map>
#include <string>
int main()
{
std::string input_sentence = "Now is the time for all good men to come to the aid of the party.";
/*
std::cout << "Input a sentence: " << std::endl;
std::getline(std::cin, input_sentence);
*/
std::map<char, int> character_counts;
for (const auto character : input_sentence)
++character_counts[character];
for (const auto counted_character : character_counts)
std::cout << counted_character.first << ": " << counted_character.second << '\n';
return 0;
}
And here is the output:
: 15
.: 1
N: 1
a: 3
c: 1
d: 2
e: 6
f: 2
g: 1
h: 3
i: 3
l: 2
m: 3
n: 1
o: 8
p: 1
r: 2
s: 1
t: 7
w: 1
y: 1

Related

Run-Time Check Failure #2 - Stack around the variable 'numberchoices' was corrupted

I am having this terminal error every time I finish the debug program.
What I am doing:
[this program is a simple Lottery Numbers Comparison between user input numbers with the non-repeated random lottery numbers. e.g. using what if it got 4 right of 6]
but it turns out that the program is not working or at least, be stable.
Here's my code:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <time.h>
#include <ctime>
#include <algorithm>
using namespace std;
int main()
{
cout << "[La Loteria Electronica]\n";
cout << "Escoge 6 n" << char(163) << "meros del (1 al 49): \n";
int numberchoices[] = { 0 };
for (int w = 1; w < 7; w++)
{
cout << "N" << char(163) << "mero #" << w << ": ";
cin >> numberchoices[w];
} // user numbers
//lottery numbers
int i, j, k, nums[51];
srand((int)time(0));
for (i = 1; i < 50; i++) nums[i] = i;
for (i = 1; i < 50; i++)
{
j = (rand() % 49) + 1;
k = nums[i]; nums[i] = nums[j]; nums[j] = k;
}
cout << "The lottery numbers are: ";
for (i = 1; i < 7; i++) cout << nums[i] << " ";
if (numberchoices[i] = nums[i])
{
cout << "gud\n";
}
if (numberchoices == nums)
{
cout << "gud 2";
}
/**/
cout << "\n\n";
system("pause");
Please ?
int numberchoices[] = { 0 };
for (int w = 1; w < 7; w++)
{
cout << "N" << char(163) << "mero #" << w << ": ";
cin >> numberchoices[w];
} // user numbers
You're declaring an array of size 1 and then you use it up to position 6 ?
I am having this terminal error every time I finish the debug program.
I'm surprised that you're not having a terminal error every time you start debug.
The access of numberchoises at positions from 1 to 6 are UB (Undefined Behavior). That is: all can happens.
Solution: try with
int numberchoices[7] = { }; // initialize all elements to zero!
Another point
if (numberchoices == nums)
not sure that you get what do you expect.
Do you want compare the integer pointer corresponding to numberchoices (a int[1], suggested int[7]) with the one corresponding to nums (a int[51]) ?

Making a program that counts the amount of occurrences for each letter in the alphabet issues

#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
string text;
int i;
char x;
int n = 0;
int main(int argc, const char * argv[])
{
cout << "Enter some text: " << endl;
getline(cin, text);
for (x = 'a'; x <= 'z'; x++)
{
for (i = 0; i<= text.length(); i++)
{
if (text[i] == x)
{
n++;
cout << x << ": " << n << endl;
}
}
}
}
So I want it to print out the occurrence for each letter that appears in the string but instead, I am getting this:
Input: hello
Output:
e: 1
h: 2
l: 3
l: 4
o: 5
I understand why it is counting up each time it finds a letter, but how do I get it to display the number of times each one of those letters actually come up. For example this is what I want it to say:
e: 1
h: 1
l: 2
o: 1
In the start of each loop(x) you should reset n to 0.
Also you should move the statment
cout << x << ": " << n << endl;
From the second loop the end of the first loop

C++ convert string array to integers, then sum int array

I need to pass an user input integer to a sumTotal(& userInt) function.
If the int is 2341 I need to sum 2+3+4+1 = 10 and return the value to main!
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// The program needs to input an integer like 2341, then sum it as 2+3+4+1 + 10
// I am in putting an integer and will pass it to a funtion by &.
int main()
{
string strNumber;
int intNumber = 0;
cout << "Enter your number: ";
cin >> intNumber;
// programming the logic for sumTotal(& intNumber) function before creating
strNumber = to_string(intNumber);
cout << "Your number is: " << strNumber << endl;
cout << "Your numbers length: " << strNumber.length() << " digits" << endl;
// here I need to convert the string array to an integer array
for (int i = 0; i < strNumber.length(); ++i){
intNumber[&i] = strNumber[i] - '0';
cout << "Element [" << i << "] contains: " << strNumber[i] << endl;
}
// next a recursive function must sum the integer array
// I am taking an online course and cant afford a tutor please help!
system("pause");
return 0;
}
if you want recursion ,you don't need any string work,try this :
#include <iostream>
using namespace std;
int recSum(int);
int main(){
int i;
cin>>i;
cout<<recSum(i);
return 0;
}
int recSum(int i){
return i==0?0:i%10+recSum(i/10);
}
recursion on array version
#include <iostream>
using namespace std;
int recSum(int* ary,int len){
return len<0?0:ary[len]+recSum(ary,len-1);
}
int main(){
int j[]={1,2,3,4,5,6,7,8,9,10};
cout<<recSum(j,9);
}
A simple and efficient method is to keep the number as a string and access the digits one at a time.
Note the equation:
digit_number = digit_character - '0';
Also, knowing that when summing digits, the order is irrelevant. So, we have:
sum = 0;
for (i = 0; i < string.length(); ++i)
{
sum += string[i] - '0';
}
A string is an array of chars. To convert a char to an int you have to do 'char' - '0'.
I wrote a couple of versions.
Pick whichever one you like best.
#include <iostream>
#include <string>
int main()
{
std::string str = "1234";
int sum = 0;
//pre C++11
for (std::string::iterator i = str.begin(); i != str.end(); ++i)
sum += (*i - '0');
//C++11
sum = 0;
for (auto i = str.begin(); i != str.end(); ++i)
sum += (*i - '0');
//ranged-for
sum = 0;
for (const auto &i : str)
sum += (i - '0');
std::cout << "Sum: " << sum;
std::cin.get();
}

Printing out correct values when reading the file but garbage after the file has been read

Question: why does it print out the correct values inside the while loop (while reading / inputting the file) but not outside the while loop? I don't understand.
Thank you very much for any help.
input file:
1
2
3
4
5
#include <iostream>
#include <string>
#include <fstream>
#include <string>
using namespace std;
int sumNumbers(int sum, int* numbers, int numElements, int count)
{
if (count == numElements) return sum;
sumNumbers(sum + numbers[count], numbers, numElements, count + 1);
return 0;
}
int main(int argc, char* argv[])
{
int* numbers;
int numElements = 0;;
int sum = 0;
string fileName = argv[2];
ifstream ifile(fileName);
if( ifile.fail() ) {
cout << "The file could not be opened. The program is terminated." << endl;
return 0;
}
while ( !ifile.eof() ) {
numbers = new int[++numElements];
ifile >> numbers[numElements - 1];
cout << "Position " << numElements - 1 << ": " << numbers[numElements - 1] << endl;
}
cout << numbers[0] << endl;
cout << numbers[1] << endl;
cout << numbers[2] << endl;
cout << numbers[3] << endl;
cout << numbers[4] << endl;
cout << "--------------\n";
for(int i = 0; i < numElements; i++) {
cout << "Position " << i << ": " << numbers[i] << endl;
}
sumNumbers(sum, numbers, numElements, 0);
cout << "The sum of the numbers in the file is: " << sum << endl;
return 0;
}
output:
Position 0: 1
Position 1: 2
Position 2: 3
Position 3: 4
Position 4: 5
0
-805306368
0
-805306368
5
--------------
Position 0: 0
Position 1: -805306368
Position 2: 0
Position 3: -805306368
Position 4: 5
The sum of the numbers in the file is: 0
You are instantiating (and leaking) a new array in each loop iteration. And you only fill one element of that array. After the loop ends, you are left with the final array, with only the last element set.
There are many questions on SO that deal with the problem of reading numbers from a file into an array or container. Here, numbers are read into an std::vector.
#include <fstream>
#include <vector>
#include <iterator>
#include <iostream>
#include <algorithm>
int main()
{
std::vector<int> numbers;
ifstream ifile(fileName);
std::istream_iterator<int> eof;
std::istream_iterator<int> it(ifile);
std::copy(it, eof, std::back_inserter(numbers));
for(int i = 0; i < numbers.size(); ++i)
{
cout << "Position " << i << ": " << numbers[i] << endl;
}
}
Alternatively, you can replace the istream_iterators and the call to std::copy by a while loop:
int n=0;
while (ifile >> n) {
numbers.push_back(n);
}
This part:
while ( !ifile.eof() ) {
numbers = new int[++numElements];
// ...
repeatedly allocates memory for numbers. At each new, previous values are lost, and the memory from the previous allocation is leaking. You can print the value correctly before the next call to new so it seems to work within the loop.
It is better to use a vector:
int new_number;
while ( ifile >> new_number) {
numbers.push_back(new_number);
// ...
and don't use file.eof() in the while condition.

C++ Random & Array

I try to use the random function for different things.
For now it works but I get one problem is I want to generate randomly the F in my code but they need to become array after. Also I need to use it and if I need to do it 1 by 1 I think my code will be too long and messy.
Do you know how I can do this?
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main(){
srand(time(0));
//random numbers 1 to 10 for Time:
int t = rand() % 10 + 1 ;
cout << "There is "<< t << " Time;
int* F1 = new int [t];
int* F2 = new int [t];
int* F3 = new int [t];
int* F4 = new int [t];
int* F5 = new int [t];
cout << "Time per F: 0 Not available, 1 available;
//For F1
for(int i = 0; i < t; i++){
//random numbers 0 or 1:
F1[i] = rand() % 2 ;
}
cout << "The Time for F1 is ";
for(int a = 0; a < t; a++){
cout << " "<< F1[a] <<" ";
}
//For F2
for(int j = 0; j < t; j++){
//random numbers 0 or 1:
F2[j] = rand() % 2 ;
}
cout << "The Time slot for F2 is ";
for(int b = 0; b < t; b++){
cout << " "<< F2[b] << " ";
}
return 0;
}
Thank you
Edit: With the solution you give me helps to find the solution
I do int F[em][t];
Since you are using C++, and have access to the standard library, this could be written much cleaner as safer as a std::vector:
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
srand(time(0));
//Random number from 3 to 7
int numberOfVectors = (rand() % 7) + 3;
//Random number from 1 to 10.
int size = (rand() % 10) + 1;
std::cout << "There are " << numberOfVectors << " vectors." << std::endl;
std::cout << "Each vector has " << size << " elements." << std::endl;
std::vector< std::vector<int> > vectorOfVectorOfInt;
std::cout << "Value per element: 0 = Not available, 1 = available" << std::endl;
for(int vec = 0; vec < numberOfVectors; vec++)
{
//Create a new vector with 'size' elements.
std::vector<int> newVector(size);
for(int i = 0; i < size; i++)
{
//Generate a random value between 0 and 50
newVector[i] = (rand() % 50);
}
//Add the vector to our vector-of-vectors.
vectorOfVectorOfInt.push_back(newVector);
std::cout << "The values for Vector #" << (vec+1) << " is:";
for(int b = 0; b < size; b++)
{
int value = vectorOfVectorOfInt[vec][b];
std::cout << "\t" << value;
}
std::cout << std::endl;
}
return 0;
}
You can run it and see the results here: http://ideone.com/RWQhjO
Use an array of array:
#include <ctime>
#include <cstdlib>
using namespace std;
int main(){
srand(time(0));
//random numbers 1 to 10 for Time:
int t = rand() % 10 + 1 ;
cout << "Time per F: 0 Not available, 1 available";
const int f_num = 5;
cout << "There is "<< t << "Time";
int* F = new int*[f_num];
for(int i = 0; i < f_num; i++){
F[i] = new int[t];
cout << "The Time for F"<<i<<" is :";
for(int j = 0; j < t; j++){
//random numbers 0 or 1:
F[i][j] = rand() % 2 ;
cout << " "<< F1[i][j] <<" ";
}
}
}
BTW, your code is C-like. In C++, we usually use std::vector instead of plain array, and http://en.cppreference.com/w/cpp/numeric/random instead of rand() . Also, don't use using namespace std . This can cause name clashes.
I try to use the random function for different things.
Random things, presumably.
For now it works but I get one problem is I want to generate randomly the F in my code but they need to become array after.
You can generate this just as you generated your value for t.
const int number_of_fs = rand() % 10 + 1;
std::cout << "Working with " << number_of_fs << " Fs" << std::endl;
Also I need to use it and if I need to do it 1 by 1 I think my code will be too long and messy. Do you know how I can do this?
Your code is already too long and messy and has memory leaks. You should be using containers from the Standard Containers library, rather than pointers to pointers that never get deleted.
Here is how your code might look were you to use a std::map of std::vectors for instance:
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iterator>
#include <map>
#include <vector>
int main(){
srand(time(0));
//random numbers 1 to 10 for Time:
const int t = rand() % 10 + 1;
std::cout << "There is "<< t << " Time" << std::endl;
const int number_of_fs = rand() % 10 + 1;
std::cout << "Working with " << number_of_fs << " Fs" << std::endl;
std::map<int, std::vector<int> > f;
std::cout << "Time per F: 0 Not available, 1 available" << std::endl;
for (int f_slot = 1; f_slot <= number_of_fs; ++f_slot) {
for(int i = 0; i < t; i++){
//random numbers 0 or 1:
f[f_slot].push_back(rand() % 2);
}
std::cout << "The Time for F" << f_slot << " is " << std::endl;
std::copy(f[f_slot].begin(), f[f_slot].end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
}
See it run!
Population and printing of the contents of these containers should probably be extracted into separate functions, of course, but I didn't want to re-write your code completely.