Counting Multi-Character Characters in String - c++

For example, how do you count the occurrence of "TJ" in OAEKOTJEOTJ?
if (s[i] == 'TJ') and (s[i] == 'T'+'J')
x += 1;
First one gives me an error, second one doesn't count. I need a beginner solution to this, I haven't learned very much about c++ commands yet. Thanks
int x = 0
string s;
cin >> s;
for (int i = 0; i < 100; i++)
if (s[i] == T || s[i] == t) && (s[i+1] == J || s[i+1] == j)
x += 1
cout << x << endl;
That's the excerpt from my code, it doesn't count any tj, tJ, Tj or TJ

Try using:
if(s[i] == 'T' && s[i+1] == 'J') // and make sure you do not run out of bounds of string with index i.
x += 1;
EDIT:
Based on your code:
int x = 0
string s;
cin >> s;
for (int i = 0; i < 100; i++)
if (s[i] == T || s[i] == t) && (s[i+1] == J || s[i+1] == j)
x += 1
cout << x << endl;
You should do it like following:
int x = 0
string s;
cin >> s;
for (int i = 0; i < s.length()-1; i++) // use size of string s.length()-1 to iterate the string instead of 100
if (s[i] == 'T' || s[i] == 't') && (s[i+1] == 'J' || s[i+1] == 'j') // compare the ascii values of characters like - 'T' 'J' etc.
x += 1
cout << x << endl;

std::string provides a function find which searches the string for substrings, including multi-character substrings (below, I am using C++11 syntax):
#include <iostream>
#include <string>
int main()
{
using namespace std;
string text { "OAEKOTJEOTJ" };
unsigned int occ { 0 };
size_t pos { 0 };
for (;;) {
pos = text.find("TJ",pos); // Search for the substring, start at pos
if (pos == string::npos) // Quit if nothing found
break;
++pos; // Continue from next position
++occ; // Count the occurrence
}
std::cout << "Found " << occ << " occurrences." << std::endl;
}
The way it's done above we advance by one character only after each match. Depending on whether/how we want to deal with overlapping matches, we might want to advance pos by the length of the search pattern. (See chris's comment as well.)

Try this:
#include <locale> // for tolower() function
string tolower(string s) {
tolower(s[0]);
tolower(s[1]);
return s;
}
...
int main() {
string s;
cin >> s;
int n = s.size(),cont = 0;
for(int i = 0; i < n ; ++i) {
if(tolower(s.substr(i,2)) == "tj") {
++cont;
}
}
cout << cont << endl;
return 0;
}

Related

Why aren't the words getting calculated properly in C++?

I was creating the program for my friend who is interested in numerology and wants a way to calculate the value of words faster. But even though there are no errors and/or warnings, but the words' values aren't being calculated correctly. For example, "mark" has a value of 9, but the program shows 2. If you can figure out what the problem is, then pls help me. Thank you so much!
My Code:
#include <iostream>
#include <string>
int value{0};
void clear();
int main(void)
{
int number{0};
std::string response;
bool run = true;
while (run)
{
clear();
value = 0;
number = 1;
response = "";
std::cout << "How many words to evalute?:\n> ";
std::cin >> number;
std::cin.ignore();
clear();
std::string* pPhrase = new std::string[number];
int* pValue = new int[number];
for (int i = 0; i < number; ++i) // could replace "number" with "sizeof(pPhrase)/sizeof(pPhrase[0])"
{
std::cout << "Enter Word #" << i+1 << " (or type your full phrase):\n> ";
std::cin >> pPhrase[i];
for (char j : pPhrase[i])
{
value = 0;
j = std::tolower(j);
if (j == 'a' || j == 'i' || j == 'j'
|| j == 'q' || j == 'y')
value += 1;
if (j == 'b' || j == 'k' || j == 'r')
value += 2;
if (j == 'c' || j == 'g' || j == 'l'
|| j == 's')
value += 3;
if (j == 'd' || j == 'm' || j == 't')
value += 4;
if (j == 'e' || j == 'h' || j == 'n'
|| j == 'x')
value += 5;
if (j == 'u' || j == 'v' || j == 'w')
value += 6;
if (j == 'o' || j == 'z')
value += 7;
if (j == 'f' || j == 'p')
value += 8;
pValue[i] = value;
value = 0;
std::cout << '\n';
clear();
}
}
std::cin.ignore();
std::cin.clear();
std::cout << "\n\n";
for (int i = 0; i < number; ++i)
std::cout << "Value of \"" << pPhrase[i] << "\": " << pValue[i] << '\n';
//std::cin.ignore();
std::cin.clear();
std::cout << "Would you like to evaluate another phrase? (Y/n):\n> ";
std::getline(std::cin, response);
delete[] pPhrase;
delete[] pValue;
if (response[0] == 'y' || response[0] == 'Y'
|| response.empty() || response[0] == ' ')
{
std::cout << "\n\n";
continue;
}
break;
}
std::cout << "Exiting...";
system("killall Terminal");
std::cout << "\n\n\n";
return 0;
}
void clear()
{
system("clear");
}
You could make your program run faster by using a lookup table:
static const int table[26] = {
/* a */ 1, /* b */ 2, /* c */ 3, /* d */ 4, /* e */ 5,
/* f */ 8, /* g */ 3, /* h */ 5, /* i */ 1, /* j */ 1,
/* k */ 2, /* l */ 3, /* m */ 4, /* n */ 5, /* o */ 7,
/* p */ 8, /* q */ 1, /* r */ 2, /* s */ 3, /* t */ 4,
/* u */ 6, /* v */ 6, /* w */ 6, /* x */ 5, /* y */ 1,
/* z */ 7,
};
// ...
if (isalpha(j))
{
const int table_index = j - 'a';
const letter_value = table[table_index];
pValue[i] = letter_value;
//...
}
Print the assembly language for your code fragment, then print the assembly language for the above code fragment. Compare.
Look at all the places where you set value to zero. You do it before main() begins (which is not very useful, actually). Then, bizarrely, you set value to zero at both the start and end of your inner for loop, which means that all the value += statements in that for loop might as well be value = statements. You keep value from accumulating value.
How to solve this? First, get rid of all the value = 0 statements inside your inner for loop. Second, add int value = 0; before the inner for loop, like this:
int value = 0;
for (char j : pPhrase[i])
{
// ...
}
At this point, you might as well get rid of int value{0}; above main(). That step isn't absolutely necessary, but that declaration of value is totally unneeded.
Also, DO NOT put system("killall Terminal"); in your sample code. It's very unfriendly, since it kills the very command line on which you want others to run your sample code.
(In general, using system() at all is a bad idea, since it's unportable.)
There are several issues. The main issue is that on line 70, pValue[i] = value; is incorrectly positioned inside the for loop.
Here is a fixed version:
#include <iostream>
#include <string>
using namespace std;
int value{0};
void clear();
int main() {
int number{0};
string response;
while (true) {
clear();
value = 0;
number = 1;
response = "";
cout << "How many words to evaluate?:\n> ";
cin >> number;
cin.ignore();
clear();
auto *pPhrase = new string[number]{};
int *pValue = new int[number]{};
for (int i = 0; i < number; ++i) // could replace "number" with "sizeof(pPhrase)/sizeof(pPhrase[0])"
{
cout << "Enter Word #" << i + 1 << " (or type your full phrase):\n> ";
cin >> pPhrase[i];
for (char j: pPhrase[i]) {
j = tolower(j);
if (j == 'a' || j == 'i' || j == 'j'
|| j == 'q' || j == 'y')
value += 1;
if (j == 'b' || j == 'k' || j == 'r')
value += 2;
if (j == 'c' || j == 'g' || j == 'l'
|| j == 's')
value += 3;
if (j == 'd' || j == 'm' || j == 't')
value += 4;
if (j == 'e' || j == 'h' || j == 'n'
|| j == 'x')
value += 5;
if (j == 'u' || j == 'v' || j == 'w')
value += 6;
if (j == 'o' || j == 'z')
value += 7;
if (j == 'f' || j == 'p')
value += 8;
cout << '\n';
clear();
}
pValue[i] = value;
value = 0;
}
cin.ignore();
cin.clear();
cout << "\n\n";
for (int i = 0; i < number; ++i)
cout << "Value of \"" << pPhrase[i] << "\": " << pValue[i] << '\n';
cin.clear();
cout << "Would you like to evaluate another phrase? (Y/n):\n> ";
getline(cin, response);
delete[] pPhrase;
delete[] pValue;
if (response[0] == 'y' || response[0] == 'Y'
|| response.empty() || response[0] == ' ') {
cout << "\n\n";
continue;
}
break;
}
cout << "Exiting...";
system("killall Terminal");
cout << "\n\n\n";
return 0;
}
void clear() {
system("clear");
}

Counting occurrence of each character in string C++

So i wanted to count all the characters in a string and categorized them in vowels, consonants, and specials character. For example;
Enter string: sentence example ..
Vowels: e(5) a(1)
Consonants: s(1) n(1) t(1) c(1) x(1) m(1) p(1) l(1)
Specials: blank space .(2)
Here's coding:
void characterType(string input)
{
int vowel = 0;
int consonant = 0;
int special = 0;
int n = input.size();
int freq[26];
memset(freq, 0, sizeof(freq));
for (int i = 0; i < n; i++)
{
freq[input[i] - 'a']++;
}
cout<<"Vowels: ";
for (int i = 0; i < n; i++)
{
char character = input[i];
if(isalpha(character))
{
character = tolower(character);
if (character == 'a' || character == 'e' || character == 'i' || character == 'o' || character == 'u')
{
cout<<input[i]<<freq[input[i] - 'a']<<" ";
}
}
}
cout<<endl;
cout<<"Consonants: ";
for (int i = 0; i < n; i++)
{
char character = input[i];
if(isalpha(character))
{
character = tolower(character);
if (character != 'a' || character != 'e' || character != 'i' || character != 'o' || character != 'u')
{
cout<<input[i]<<freq[input[i] - 'a']<<" ";
}
}
}
cout<<endl;
cout<<"Specials: ";
for (int i = 0; i < n; i++)
{
char character = input[i];
if(!isalpha(character))
{
if(character == ' ')
{
cout<<"[black space]"<<freq[input[i] - 'a']<<" ";
}
else
cout<<input[i]<<freq[input[i] - 'a']<<" ";
}
}
}
And heres what ive got so far:
How do i make it not repeat the same character and why does special characters is not counting?
Since you want to do this and it's not some type of assignment, here's how I would approach the problem, using modern C++ features:
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
int main() {
std::map<char, std::size_t> occurrance;
std::string input{"This is A long string with lots of characters in it. AAA$#!#$!^^! "};
auto is_vowel = [] (char c) -> bool
{
auto lc = std::tolower(c);
return
c == 'a' ||
c == 'e' ||
c == 'i' ||
c == 'o' ||
c == 'u';
};
auto is_special = [] (char c) -> bool
{
// use ascii table to find only "non-special characters"
if(c < '0') return true;
if(c > '9' && c < 'A') return true;
if(c > 'Z' && c < 'a') return true;
if(c > 'z') return true;
return false;
};
auto vowels = std::count_if(
input.begin(),
input.end(),
is_vowel);
auto special = std::count_if(
input.begin(),
input.end(),
is_special);
for(auto c : input)
{
occurrance[c] += 1;
}
std::cout << "Vowels: " << vowels << '\n';
std::cout << "Special: " << special << '\n';
for(auto [c, count] : occurrance)
{
std::cout << c << " -> " << count << '\n';
}
return 0;
}
https://ideone.com/YVaDiI
This does the job, although you can make the output prettier... and take the uppercase letters into account.
void printCharWithFreq(string str)
{
int v=0, c=0, s=0;
// size of the string 'str'
int n = str.size();
// 'freq[]' implemented as hash table
int freq[SIZE];
// initialize all elements of freq[] to 0
memset(freq, 0, sizeof(freq));
// accumulate freqeuncy of each character in 'str'
for (int i = 0; i < n; i++)
freq[str[i] - 'a']++;
// traverse 'str' from left to right
for (int i = 0; i < n; i++) {
// if frequency of character str[i] is not
// equal to 0
if (freq[str[i] - 'a'] != 0) {
// print the character along with its
// frequency
if(str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o' || str[i] == 'u' ||
str[i] == 'A' || str[i] == 'E' || str[i] == 'I' || str[i] == 'O' || str[i] == 'U')
{ cout<<"Vowel: " << str[i] << freq[str[i] - 'a'] << " "<<endl; v+=freq[str[i] - 'a']; }
else if(str[i] == ' ' || str[i] == '.')
{ cout<<"Specials"<<endl; s++; }
else
{ cout<<"Consonant: " << str[i] << freq[str[i] - 'a'] << " "<<endl; c+=freq[str[i] - 'a']; }
// update frequency of str[i] to 0 so
// that the same character is not printed
// again
freq[str[i] - 'a'] = 0;
}
}
cout<<"Number of vowels: "<<v<<endl;
cout<<"Number of consonants: "<<c<<endl;
cout<<"Number of specials "<<s<<endl;
}
Then test it in the main function like
int main() {
string str = "some text . .";
printCharWithFreq(str);
return 0;
}
Basically, frequency is updated so it doesn't print the same character again, as it says in the comments. You also made a mistake in your code where you wrote:
character != 'a' || character != 'e' || character != 'i' || character != 'o' || character != 'u'
It is a consonant only if the input is different than ALL of the vowels, meaning you have to put &&, not ||.
As for the special characters, they can be counted with a simple counter.
The rest, I think, is clear from the comments in the code.
I adapted the code from the following source:
https://www.geeksforgeeks.org/print-characters-frequencies-order-occurrence/

Why does the program print 0 instead of the average?

Wrote a function that calculates the average length of words in a sentence.
Why does the program print 0 instead of the average?
Please help me fix my mistake.
If you know how to make an implementation in one function, please write.
#include <iostream>
#include <string>
using namespace std;
int CountWordsAndLetters(char* str, int& words, int& letters)
{
words = 0;
int i = 0;
letters = 0;
while (str[i] == ' ')
i++;
for (; str[i]; i++) {
if (((str[i] >= 'a') && (str[i] <= 'z'))
|| ((str[i] >= 'A') && (str[i] <= 'Z')))
letters++;
if (str[i] == ' ') {
words++;
while (1)
if (str[i] == ' ')
i++;
else {
i--;
break;
}
}
}
words = words + 1;
return (words);
}
float AverageLetters(float words, float letters)
{
float a = (double)(letters / words);
return a;
}
int main()
{
char array[255];
int words = 0;
int letters = 0;
cout << "Enter the string\n\n";
gets_s(array);
int size;
for (size = 0; array[size]; size++)
;
char* str = new char[size];
CountWordsAndLetters(str, words, letters);
cout << "\nAverage number of letters per word: "
<< AverageLetters(words, letters);
return 0;
}
If you know how to make an implementation in one function, please write.
Here, you are allocating an uninitialized array of char:
char* str = new char[size];
You put nothing in it.
You then pass it to CountWordsAndLetters:
// here -------v
CountWordsAndLetters(str, words, letters);
You should consider simply sending array instead:
CountWordsAndLetters(array, words, letters);
Here's a live example of your code working.

My Code for Erasing Empty Spaces in a Sentence in C++ has an Issue

I have made this code such that whatever I type in a sentence has the first letter of the first word capitalized; While reducing any number of spaces in a sentence to just one space. However, my sentences are only reducing by one space. For example, if I put 3 spaces in a sentence, the output has spaces reduced by 1 to 2 spaces, but I want the output of words in a sentence to have only one space. I can't quite figure out what is wrong with my code and hence any help would be greatly appreciated. I have attached my code for reference below:
#include <stdio.h>
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
int i = 0; //i for counter
string str;
//String variable
getline(cin, str); //Get string from user
int L = str.length(); //Find length of string
//Display original string
for (int i = 0; i < 100; i++)
{
str[i] = tolower(str[i]);
}
str[0] = toupper(str[0]);
bool space;
for (int j = i + 1; j < L; j++)
{
str[j] = str[j + 1];
L--;
}
cout << str << endl;
return 0;
}
Or doing it in a more modern way using iterators :
#include <iostream>
#include <cctype>
int main() {
std::cout << "This is the string trimming function.\n" <<
"Throw in a string and I will make sure all extra spaces " <<
"will be reduced to single space.\n";
std::string InputString, TrimmedString;
int head = -1;
int tail = -1;
std::cout << "Please enter the input string :\n" << std::endl;
std::getline(std::cin, InputString);
for(std::string::iterator it = InputString.begin(); it <= InputString.end(); it++){
if (*it != ' ' && head < 0 && tail < 0) {
head = std::distance(InputString.begin(), it);
}
else if (head >= 0 && tail < 0 && (*it == ' ' || it == InputString.end())) {
tail = std::distance(InputString.begin(), it);
TrimmedString.append(InputString, head, (tail-head));
TrimmedString.push_back(' ');
head = -1;
tail = -1;
}
}
TrimmedString[0] = toupper(TrimmedString[0]);
std::cout << "\nThe processed string is :\n\n" << TrimmedString << std::endl;
return 0;
}
Try this:
int main()
{
std::string str;
std::getline(cin, str);
//Change case
str[0] = toupper(str[0]);
std::transform(str.begin() + 1, str.end(), str.begin() + 1, ptr_fun<int, int>(tolower));
//Parsing time
for (int i = 0; i <= str.size() - 1; i++)
{
if (str[i] == ' ' && str[i + 1] == ' ') //if present & next are whitespaces, remove next
{
str.erase(str.begin() + i);
i--; // rechecking condition
}
}
std::cout << '\n' << str << '\n';
}
Output:

c++ Expression: string subscript out of range error

hello i am new to programming but every time i run this code i get the error "c++ Expression: string subscript out of range" i am pretty sure that the error is in the second for loop
#include<iostream>
#include<string>
#include <algorithm>
using namespace std;
int main()
{
string x;
string n;
cin >> x;
for (int i = 0; i <= x.length(); i++){
if (x[i] == 'a' || x[i] == 'e' || x[i] == 'i' || x[i] == 'o' || x[i] == 'u' || x[i] == 'y')
{
x[i] = ' ';
}
}
x.erase(remove_if(x.begin(), x.end(), isspace), x.end());
int f = x.length() * 2;
for (int i = 0; i <f-1; i+=2){
n[i] = '.';
}
cout << n << endl;
}
for (int i = 0; i <= x.length(); i++)
should be:
for (int i = 0; i < x.length(); i++)
because index starts from 0
x[x.length()] out of range
can not use n[index] when the size of n is 0,use n.push_back()
for (int i = 0; i < x.length(); i++){ //error
if (x[i] == 'a' || x[i] == 'e' || x[i] == 'i' || x[i] == 'o' || x[i] == 'u' || x[i] == 'y')
{
x[i] = ' ';
}
}
x.erase(remove_if(x.begin(), x.end(), isspace), x.end());
int f = x.length() * 2;
for (int i = 0; i <f-1; i+=2){
n[i] = '.'; // n.push_back('.');
}
cout << n <
< endl;
If you are trying to remove all the vowels from your input string, you do not need to run two separate loops. You are already using std::remove_if, just add lambda shown in following code and you will have your desired output.
#include <iostream>
#include <algorithm>
#include <string>
#include <cctype>
using namespace std;
int main() {
std::string str = "This is test of vowels aeiou to be removed. Also the upper case AEIOU.";
std::cout << "Original String: " << str << std::endl;
str.erase(std::remove_if(str.begin(), str.end(), [](char x) {
return (x == 'a'|| x == 'e' || x == 'i' || x == 'o' || x == 'u' || x == 'y'
|| x == 'A'|| x == 'E' || x == 'I' || x == 'O' || x == 'U' || x == 'Y')
}), str.end());
std::cout << "String with vowels removed: " << str << std::endl;
// Not sure what you are trying to achieve with this code.
int f = x.length() * 2;
for (int i = 0; i <f-1; i+=2)
{
n[i] = '.';
}
return 0;
}
Here is the LiveDemo
You have 3 bits of code causing errors:
1) Your first error occurs because you should be checking that i < x.length() in the first loop condition, not that i <= x.length() . Even better, calculate the length once and then use that value in the loop condition to avoid calling x.length() repeatedly. Your first loop should look like this:
int length = x.length();
for (int i = 0; i < x.length(); ++i)
note: ++i is quicker than i++ and in this case using ++i would not make a difference to the logic.
2) Your second error is due to the line int f = x.length() * 2 because you are doubling the length of the array and then using that number to iterate through the array. For example, if your array has a length() of 5 then int f = x.length() * 2 would mean that f = 10 but if the length of the array is 5 than accessing the array with any number greater than 4 (array index starts at zero) would produce an error. In your second loop condition you do this
for (int i = 0; i < f-1; i+=2 ) {
n[i] = '.' // i could easily be more than 4 at this point
}
To fix you second problem, take out the * 2 from int f = x.length() * 2
3) Your third is because you haven't given the n string object a value yet you are accessing it using array indexing []