How to count occurrences of individual letters - c++

Task: Write a program that will read a line of text and output the number of occurrences each letter.
#include <iostream>
#include <string>
#include <cstring>
#define N 100
using namespace std;
int main()
{
char alphabet[27] = "abcdefghijklmnopqrstuvwxyz";
int alphacount[26];
char lot[N], *p1;
int txtlen, *p2;
cout << " Enter a line of text: " << endl;
cin.getline(lot, 99);
txtlen = strlen(lot);
p1 = lot;
p2 = &txtlen;
for (int x = 0; x < *p2; x++)
{
for (int y = 0; y < 26; y++)
{
if (*p1 == alphabet[y])
{
alphacount[y]++;
p1++;
}
}
}
cout <<;
}
What is the condition needed, and what variable will be used to output the occurrences of letter? For example:
> enter a line of text : mervlala
Output:
a - 2,
e - 1,
l - 2,
m - 1,
r - 1,
v - 1

You are programming on c++, you should use the c++ way.
#include <algorithm>
int main ()
{
std::string textline;
std::getline (std::cin,textline);
for(char ch = 'a'; ch <= 'z'; ch++)
{
std::size_t n = std::count(textline.begin(), textline.end(), ch);
if(n > 0)
std::cout << " - " << n << "," << std::endl;
}
}

Related

I am trying to change the order of english alphabets in a string such that for a it shall be z, for b it shall be y, etc.. and vice versa

I am trying to replace each occurrence of the letter 'a' by the letter 'z', each occurrence of 'b' by 'y', etc, and each occurrence of 'z' by 'a'....in a string. But the code is not giving desired output...
int main()
{
string S;
cin >> S;
string alphabet = "abcdefghijklmnopqrstuvwxyz";
string reversed = "zyxwvutsrqponmlkjihgfedcba";
int N = S.length();
for(int i = 0; i < N; i++)
{
for(int z = 0; z < 26; z++)
{
if(S[i] == alphabet[z])
{
S[i] = reversed[z];
}
}
}
cout << S << endl;
}
If you're using ASCII you can do this:
int main()
{
std::string S;
std::cin >> S;
std::for_each(std::execution::par_unseq, S.begin(), S.end(),
[](char &c) { c = 'a' + 'z' - c; });
std::cout << S << std::endl;
}
Your logic is flawed:
for(int i = 0; i < N; i++)
{
for(int z = 0; z < 26; z++)
{
if(S[i] == alphabet[z])
{
S[i] = reversed[z];
}
}
}
As reversed is the reversed of alphabet, whenever you encounter S[i]== alphabet[z] you will replace the letter, but after that you will encounter the replaced letter again in alphabet.
Example: You replace a by z but then at the end of the loop you find z and replace that by a.
To avoid replacing the replaced character, break from the loop after you replaced it:
for(int i = 0; i < N; i++)
{
for(int z = 0; z < 26; z++)
{
if(S[i] == alphabet[z])
{
S[i] = reversed[z];
break;
}
}
}
Note that there is a more efficient solution, as characters a till z have consecutive values you can look them up directly instead of using a loop.
Moreover, you really should have used a debugger to see what the code does. It is simple code like this that is a good opportunity to learn how to use a debugger.
Here is my five cents.:)
#include <iostream>
#include <string>
#include <cctype>
#include <cstring>
int main()
{
const char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
const size_t N = sizeof( alphabet ) - 1;
std::string s( alphabet );
// std::cin >> s;
for (auto &c : s)
{
if (const char *p = std::strchr( alphabet, std::tolower( ( unsigned char )c ) ) )
{
size_t i = p - alphabet;
if (std::isupper( c ))
{
c = std::toupper( alphabet[N - i - 1] );
}
else
{
c = alphabet[N - i - 1];
}
}
}
std::cout << alphabet << '\n';
std::cout << s << '\n';
}
The program output is
abcdefghijklmnopqrstuvwxyz
zyxwvutsrqponmlkjihgfedcba
Pay attention to that the user can enter a symbol that is not present in the alphabet or a letter in the upper case. The program should correctly process such situations.
For example if the user will enter the string "AbcxyZ" then the program output will be
ZyxcbA
You could write a separate function that does the task. For example.
#include <iostream>
#include <string>
#include <cctype>
#include <cstring>
std::string & reverse_letters( std::string &s )
{
const char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
const size_t N = sizeof( alphabet ) - 1;
for (auto &c : s)
{
if (const char *p = std::strchr( alphabet, std::tolower( ( unsigned char )c ) ))
{
size_t i = p - alphabet;
if (std::isupper( c ))
{
c = std::toupper( alphabet[N - i - 1] );
}
else
{
c = alphabet[N - i - 1];
}
}
}
return s;
}
int main()
{
std::string s( "AbcxyZ" );
std::cout << s << '\n';
std::cout << reverse_letters( s ) << '\n';
s.assign( "A1b2y3Z4" );
std::cout << s << '\n';
std::cout << reverse_letters( s ) << '\n';
}
The program output is
AbcxyZ
ZyxcbA
A1b2y3Z4
Z1y2b3A4

Checking if guessed string has a correct character at the wrong position

I want to generate a random string with letters a,b,c,d then let the user guess it.
My output should be which positions the user guessed correctly and how many letters the user guessed correctly but put them in the wrong position.
Current attempt:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
int main()
{
char lettres[4] =
{
'a',
'b',
'c',
'd'
};
char rString[4];
int i = 0;
srand(time(0));
while (i < 4)
{
int temp = rand() % 4;
rString[i] = lettres[temp];
i++;
}
int u = 0;
char t[4];
while (u < 10)
{
cout << "Enter your guess:\n ";
cin >> t;
for (int z = 0; z < 4; z++)
{
cout << rString[z] << ", "; //printing random string
}
cout << "\n";
int k;
int compteur = 0;
int t2[4];
int compteur2 = 0;
for (k = 0; k < 4; k++)
{
if (rString[k] == t[k]) //rString is my random string
{
t2[compteur2] = k;
compteur2++;
}
}
for (int y = 0; y < 4; y++)
for (int j = 0; j < 4; j++)
{
if (t[y] == rString[j] && y != j) //checking correct letters at wrong positions
{
compteur++;
t[y] = 'z'; //I put this line to avoid counting a letter twice
}
}
if (compteur2 == 4)
{
cout << "bravo\n";
u = 10;
} else
{
cout << "Positions with correct letters:\n ";
if (compteur2 == 0)
{
cout << "None";
cout << " ";
} else
for (int z = 0; z < compteur2; z++)
c out << t2[z] << ", ";
cout << " \n";
cout << "You have a total of " << compteur << " correct letters in wrong positions\n";
}
u++;
}
return 1;
}
Sample output:
Enter your guess:
abcd
b, a, b, a, //note this is my random string I made it print
Positions with correct letters:
None
You have a total of 1 correct letters in wrong positions
for example here I have 2 correct letters in the wrong position and I am getting 1 as an output
To clarify more about why I put t[y]='z'; if for example the random string was "accd" and my input was "cxyz" I would get that I have 2 correct letters at wrong positions, so I did that in attempt to fix it.
Any help on how to do this?
You should implement like this
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
int main() {
srand(time(0));
char lettres[4] = {'a','b','c','d'};
char rString[4];
int i = 0;
//making random string
while (i < 4) {
int temp = rand() % 4;
rString[i] = lettres[temp];
i++;
}
int u = 0;
char t[4];
while (u < 10) {
cout << "Enter your guess:\n ";
cin >> t;
//printing random string
for (int z = 0; z < 4; z++) {
cout << rString[z] << ", ";
}
cout << "\n";
int correctPositions = 0;
cout << "Correct Position Are:\n";
for (int z = 0; z < 4; z++) {
if (rString[z] == t[z]) {
cout << (z + 1) << ", ";
correctPositions++;
}
}
if (correctPositions == 4) {
cout << "\nBingo!" << "\nThat's Right!";
return 0;
}
if (correctPositions == 0) {
cout << "None";
}
cout << "\n";
//finding no of correct letters in wrong position:
int correctLetters = 0;
for (int i = 0; i < 4; i++) {
char c = lettres[i];
int randomCount = 0;
int guessCount = 0;
int letterInCorrectPos = 0;
for (int z = 0; z < 4; z++) {
if (rString[z] == c) {
randomCount++;
}
if (t[z] == c) {
guessCount++;
}
if (rString[z] == t[z] && t[z] == c)
letterInCorrectPos++;
}
correctLetters += min(guessCount, randomCount) - letterInCorrectPos;
}
cout << "No. of correct letters but in wrong position :" << correctLetters;
cout << "\n\n";
u++;
}
return 0;
}
Explaining Logic
1. Finding No. Of Correct Positions:
This is done by iterating with z = 0 -> z=4 over the rString and t if rString[z] is t[z] (the char at z are matching) then we just print the position!
2. Finding No. Of Correct Letters In Wrong Position
This part was little tricky to implement but here is the method I followed.
We have lettres[] array which is containing all the letters, right? We will now individual loop over each letter in the array and count the no. of occurrence in the rString and t, and store the respective counts in a randomCount and guessCount respectively.
Ex. let rString = "bdcc" and t = "abcd" so we have the following data:
'a': randomCount:0 guessCount:1 letterInCorrectPos: 0
'b': randomCount:1 guessCount:1 letterInCorrectPos: 0
'c': randomCount:2 guessCount:1 letterInCorrectPos: 1
'd': randomCount:1 guessCount:1 letterInCorrectPos: 0
This is the first part in the above loop you can see we have another variable letterInCorrectPos, this variable stores the no. of instances in the string where, the letter is at the same position in both the strings.
Figuring these three values we can calculate the no. of correct letter:
correctLetters = min(guessCount, randomCount)
the smaller value of guessCount or randomCount is chosen because we don't want repeated counting. (We can't have more correct letters than there are instances of that letter in another class).
Now by simple logic: correct letters in wrong place is (correct letters) - (correct letters in the correct place ).Hence,
correctLetters = min(guessCount, randomCount) - letterInCorrectPos;
Since we are iterating in a loop and we want to add correctLetters of each letter, we use this statement at the end of loop:
correctLetters += min(guessCount, randomCount) - letterInCorrectPos;
Hope this will explain the working.

add space after space in char array

So, i need to insert space after space in char string, for example:
we have string: hello world, and function should be return hello world
hello world something else => hello world something else
hello world => hello world (4 spaces) (not necessarily, but preferably)
how?? (definitely need to be used char string)
my solution (it does not work correctly because it insert only 1 space)
from hello world something it returns hello world something:
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
char* addSpaces(char* str) {
char* p = strchr(str, ' ');
if (p) {
p++;
int n = strlen(p);
p[n + 1] = 0;
while (n) {
p[n] = p[n - 1];
n--;
}
*p = ' ';
}
return str;
}
int main(void) {
const int stringCount = 1;
const int c = 500;
char cstring[stringCount][c];
string str[stringCount];
for (int i = 0; i < stringCount; i++) {
cout << "Enter " << i + 1 << ". line: ";
cin.getline(cstring[i], c);
str[i] = cstring[i];
}
for (int i = 0; i < stringCount; i++) {
cout << "First function result with char in parameter: ";
char* result = addSpaces(cstring[i]);
cout << result << endl;
}
}
Using Dynamic Array:
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
char *add(char *arr, int lastIndex, char key)
{
int len = sizeof(&arr);
if (len == 0 || arr[len - 1] != '\0')
{
char newArr[len + 100];
newArr[len + 100 - 1] = '\0';
strncpy(newArr, arr, len);
*arr = *newArr;
}
arr[lastIndex] = key;
return arr;
}
int main(void)
{
std::string line;
const int stringCount = 1;
const int c = 500;
cout << "Enter line: ";
std::getline(std::cin, line);
int spaceCount = 0;
char cstring[0];
int lastUpdated = 0;
for (int i = 0; i < sizeof(line); i++)
{
add(cstring, lastUpdated++, line[i]);
if (line[i] == ' ')
{
add(cstring, lastUpdated++, ' ');
}
}
cout << cstring << endl;
}
OR
Check for space first and start char str with len+spaces. and add extra space on each iterate. Else error out of index bound can come.
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main(void)
{
std::string line;
const int stringCount = 1;
const int c = 500;
cout << "Enter line: ";
std::getline(std::cin, line);
cout << line << endl;
int spaceCount = 0;
for (int i = 0; i < sizeof(line); i++)
{
if (line[i] == ' ')
{
spaceCount += 1;
}
}
char cstring[stringCount + spaceCount];
int j = 0;
for (int i = 0; i < sizeof(line); i++)
{
if (line[i] == ' ')
{
cstring[j++] = ' ';
cstring[j++] = ' ';
}
else
{
cstring[j++] = line[i];
}
}
cout << cstring << endl;
}
Modify the main() function according to your needs:
#include <iostream>
#include <cstring>
#include <cstdlib>
#define MAXLEN 500
void add_space(char* str, size_t index, size_t n) {
if (n >= MAXLEN) {
std::cerr << "Cannot further expand the array!" << std::endl;
abort();
}
for (auto i = n; i >= index; --i)
str[i] = str[i - 1];
str[index] = ' ';
}
char* double_spaces(char* str, size_t n) {
for (size_t i = 0; i < n; ++i)
if (str[i] == ' ')
add_space(str, i++, n++);
return str;
}
int main() {
char str[MAXLEN] = "hello world";
std::cout << double_spaces(str, std::strlen(str)) << std::endl;
return 0;
}
Sample Output:
For str[] = "hello world" function returns "hello world"
For str[] = "hello world something else" function returns "hello world something else"
For str[] = "hello world" function returns "hello world"
PS: Better algorithms are possible but they mostly require use of advanced data structures so sticking to the asker's demand of using simple cstrings I have provided one of the simplest and easy to understand solution.
Analysis: The insertion operation requires O(n-index) time which can be reduced by using something similar to ArrayLists.

How do I count the occurences of each digit in a string using int* count (const string& s) in c++?

Note: I can't use maps or anything in the algorithm library
I only have the main function, but am completely lost on how I'm supposed to write the function
#include <string>
#include <iostream>
using namespace std;
int* count(const string& s);
int main() {
string userinput = "random word";
int *counts = count(userinput);
for (int i = 0; i < 11; i++) {
cout << "Letter " << i << " occured " << counts[i] << " times.";
}
system("pause");
return 0;
}
int* count(const string& s) {
for (int i = 0; i < 11; i++)
{
return s[i];
}
}
The int* count function is not correct and will not compile. How can I write a function that will work in returning the occurences?
How do I count the occurences of each digit in a string using int*
count (const string& s) in c++? Note: I can't use maps or anything in
the algorithm library
A few things to note:
Always bad idea, if we don't follow the simplest way of approaching a problem and it's sad that teachers are the promoters of such situations.
There is not need of a int*. which does not provide your solution at any manner. If it would have been array to count the chars of your string, then it might make sense(i.e, pointer to the array).
Try to avoid practicing with using namespace std;
You can do something like as follows, if you are not allowed to use std::map<char, int>(hint for your alternative solution).
I have commented on it, for better understanding.
#include <string>
#include <iostream>
#include <cstddef>
// consider 128 ASCII decimal and their coresponding character codes
int charASCIIArray[128] = {0};
void count_char(const std::string& s)
{
for(const auto& it: s)
{
if(('A' <= it && it <= 'Z') || // if char between (A,B,....,Z) or
('a' <= it && it <= 'z') ) // between (a,b,....,z)
charASCIIArray[static_cast<int>(it)]++; // we count each corresponding array then
}
}
int main()
{
std::string userinput = "random words WITH *- aLl";
count_char(userinput);
for(std::size_t index = 0; index < 128; ++index)
if(charASCIIArray[index] != 0)
std::cout << "Letter " << static_cast<char>(index) // convert back to char
<< " occured " << charASCIIArray[index] << " times.\n";
return 0;
}
See live action here: https://www.ideone.com/uFG2HJ
Letter H occured 1 times.
Letter I occured 1 times.
Letter L occured 1 times.
Letter T occured 1 times.
Letter W occured 1 times.
Letter a occured 2 times.
Letter d occured 2 times.
Letter l occured 1 times.
Letter m occured 1 times.
Letter n occured 1 times.
Letter o occured 2 times.
Letter r occured 2 times.
Letter s occured 1 times.
Letter w occured 1 times.
UPDATE
Inspired from #Fei Xiang's comment, here is two over engineered solutions:
Firstly, with returning pointer to a dynamic array(which will meet actual
question requirements): https://www.ideone.com/ouHqK4
#include <string>
#include <iostream>
#include <cstddef>
int* count_char(const std::string& s)
{
// consider 128 ASCII decimal and their coresponding character codes
int *charASCIIArray = new int[128]{0};
for(const auto& it: s)
{
if(('A' <= it && it <= 'Z') || // if char between (A,B,....,Z) or
('a' <= it && it <= 'z') ) // between (a,b,....,z)
charASCIIArray[static_cast<int>(it)]++; // we count each corresponding array then
}
return charASCIIArray;
}
int main()
{
std::string userinput = "random words WITH *- aLl";
int *charASCIIArray = count_char(userinput);
for(std::size_t index = 0; index < 128; ++index)
if(charASCIIArray[index] != 0)
std::cout << "Letter " << static_cast<char>(index) // convert back to char
<< " occured " << charASCIIArray[index] << " times.\n";
delete[] charASCIIArray;
return 0;
}
Secondly with smart pointer(std::unique_ptr) : https://www.ideone.com/dfc62J
#include <string>
#include <iostream>
#include <cstddef>
#include <memory>
#include <utility>
std::unique_ptr<int[]> count_char(const std::string& s)
{
// consider 128 ASCII decimal and their coresponding character codes
std::unique_ptr<int[]> charASCIIArray = std::unique_ptr<int[]>(new int[128]{0});
for (const auto& it : s)
{
if (('A' <= it && it <= 'Z') || // if char between (A,B,....,Z) or
('a' <= it && it <= 'z')) // between (a,b,....,z)
charASCIIArray[static_cast<int>(it)]++; // we count each corresponding array then
}
return std::move(charASCIIArray);
}
int main()
{
std::string userinput = "random words WITH *- aLl";
std::unique_ptr<int[]> charASCIIArray = count_char(userinput);
for (std::size_t index = 0; index < 128; ++index)
if (charASCIIArray[index] != 0)
std::cout << "Letter " << static_cast<char>(index) // convert back to char
<< " occured " << charASCIIArray[index] << " times.\n";
return 0;
}
Not so sure you wanted this answer but I hope it helps
you can seperate it into seperate function but I did it in a single go
#include <iostream>
#include <string>
using namespace std;
int main()
{
string userInput = "random word";
int fCharacter[256];
for (int i = 0; i <= 255; i++)
{
fCharacter[i] = 0;
}
for (int i = 0; i < userInput.length(); i++)
{
fCharacter[userInput[i]]++;
}
cout << "The character changes are as follows" << endl;
for (int i = 0; i <= 255; i++)
{
if (fCharacter[i] != 0)
{
cout << (char)i << endl;
}
}
system("pause");
return 0;
}

I am getting a c++ program crash when trying to display a string diagonally

My program is crashing when I run it, I ran the debugger and it reports this:
std::out_of_range at memory location 0x0066F6F4.
My code is as follows:
#include <iostream>
#include <string>
int main() {
std::string name = "Alexi";
for (unsigned int i = 0; i <= name.length(); i++) {
for (unsigned int x = 0; x <= i; x++) {
if (i == x) std::cout << name.at(x);
else std::cout << " ";
}
std::cout << '\n';
}
return 0;
}
Any help would be appreciated.
You should have i < name.length() and not i <= name.length()
#include <iostream>
#include <string>
int main() {
std::string name = "Alexi";
for (unsigned int i = 0; i < name.length(); i++) {
for (unsigned int x = 0; x <= i; x++) {
if (i == x) std::cout << name.at(x);
else std::cout << " ";
}
std::cout << '\n';
}
return 0;
}
The string name has the length of 5.
Internally, it is stored in a char [] (character array) called namewhere the
character A is stored at name[0]
character l is stored at name[1]
character e is stored at name[2]
character x is stored at name[3]
character i is stored at name[4]
So note that the length was 5 but your maximum index is 4.
This is because C and C++ arrays are 0-indexed