get vowels from char in C++ - c++

#include <iostream>
using namespace std;
char a[20];
int main()
{
cin >> a;
}
If I write for a="home", I want to take the vowels ("o" and "e") and replace them with capital letters ("O" and "E"). how do I do that?
EDIT:
Your answers where very helpful. I did something like this:
cin >> a;
for (int i = 0; a[i] != '\0' && i <= 20; i++)
{
if (a[i] == 'a')
a[i] = 'A';
if (a[i] == 'e')
a[i] = 'eE';
if (a[i] == 'i')
a[i] = 'iI';
if (a[i] == 'o')
a[i] = 'oO';
if (a[i] == 'u')
a[i] = 'uU';
}
I wanted to change for exemple "e" into "eE" but it doesn't work...

Write a function which will tell you whether something is a vowel or not. This can be as simple as looping through an array or using std::set.
Iterate through the characters and replace the vowels with the return value of toupper.
As a secondary note, you probably want to use std::string instead of char[].

Basically, you can do this:
#include <iostream>
using namespace std;
char a[20];
int main(){
cin >> a;
for (int i = 0; a[i] != '\0' && i < 20; i++){
if (a[i] == 'a' || a[i] == 'e' || a[i] == 'i'|| a[i] == 'o'|| a[i] == 'u'){
a[i] = a[i] + 'A' - 'a';
}
}
cout << a;
}
The program iterates each character in the string, and compares it to all five vowels. If it finds it is a vowel, it turns it into uppercase.
The line
a[i] = a[i] + 'A' - 'a';
may seem hard to understand, but it isn't. Every character is actually an integer in a coding system. In most coding systems, the difference between a letter and its corresponding capital letter is a constant given by ('A' - 'a'). So, by adding ('A' - 'a') to any character, you effectively turn it into uppercase.

//inside the loop body
cin >> a;
while(a[i])
if(a[i] == 'a' || a[i] == 'e' || a[i] == 'i' || a[i]== 'o' || a[i]=='u')
{
a[i]=toupper(a[i]);
}

Related

How do I modify an input through multiple functions in C++?

Basically I have to encode a name into a Soundex Code. The helper functions I implemented do the following:
Discard all non-letter characters from the surname: dashes, spaces, apostrophes, and so on.
Encode each letter as a digit
Coalesce adjacent duplicate digits from the code (e.g. 222025 becomes 2025).
Replace the first digit of the code with the first letter of the original name, converting to uppercase.
Remove all zeros from the code.
Make the code exactly length 4 by padding with zeros or truncating the excess.
Excuse the implementation of the helper functions, I know they could be implemented better. But when I manually pass the output from one function to another I see that the result is what I want. It's only when I combine them all into one function that I see that the output I pass is as if I didn't modify the input I passed at all. I believe my issue might have to do with passing by reference but doing that for all my functions made no difference or gave an incorrect output.
#include <iostream>
#include <string>
string removeNonLetters(string s) {
string result = "";
for (int i = 0; i < s.length(); i++) {
if (isalpha(s[i])) {
result += s[i];
}
}
return result;
}
string encode(string name) {
std::transform(name.begin(), name.end(), name.begin(), ::toupper);
string encoded = "";
for (int i = 0; i < name.size(); ++i) {
if (name[i] == 'A' || name[i] == 'E' || name[i] == 'I' || name[i] == 'O' || name[i] == 'U' || name[i] == 'H' || name[i] == 'W' || name[i] == 'Y')
encoded += '0';
else if (name[i] == 'B' || name[i] == 'F' || name[i] == 'P' || name[i] == 'V')
encoded += '1';
else if (name[i] == 'C' || name[i] == 'G' || name[i] == 'J' || name[i] == 'K' || name[i] == 'Q' || name[i] == 'S' || name[i] == 'X' || name[i] == 'Z')
encoded += '2';
else if (name[i] == 'D' || name[i] == 'T')
encoded += '3';
else if (name[i] == 'L')
encoded += '4';
else if (name[i] == 'M' || name[i] == 'N')
encoded += '5';
else if (name[i] == 'R')
encoded += '6';
}
return encoded;
}
string removeDuplicate(string encoded) {
for (int i = 0; i < encoded.size(); ++i) {
if (encoded[i] == encoded[i+1])
encoded[i] = '\0';
}
return encoded;
}
string removeZeros(string digits) {
for (int i = 0; i < digits.size(); ++i) {
if (digits[i] == '0')
digits[i] = '\0';
}
return digits;
}
string padding(string output) {
int size = output.size();
if (size < 4) {
for (int i = size; i < 4; ++i)
output += '0';
}
else if (size > 4) {
for (int j = size; j > 3; --j)
output[j] = '\0';
}
return output;
}
/* TODO: Replace this comment with a descriptive function
* header comment.
*/
string soundex(string s) {
/* TODO: Fill in this function. */
string copy = s;
removeNonLetters(s);
encode(s);
removeDuplicate(s);
s[0]= copy[0];
removeZeros(s);
padding(s);
return s;
}
int main() {
string s = "Curie";
cout << soundex(s) << '\n';
// Output should be C600 but I keep getting "Curie."
}
Your functions return the adjusted strings, that's good. But your calling code doesn't use the returned values!
Something like this is what you want.
string soundex(string s) {
/* TODO: Fill in this function. */
string copy = s;
s = removeNonLetters(s);
s = encode(s);
s = removeDuplicate(s);
s[0] = copy[0];
s = removeZeros(s);
s = padding(s);
return s;
}
If you want to change the value of a variable you normally use =. I'm sure you know that but for some reason you forgot because functions are involved.

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 is the code is not removing "u" from the input string?

I am learning C++. Today I have written a code to remove vowels form a string. It works fine in some tests. But this test is failing to remove "u" from a string.
My input was: tour.
Output was: tur.
But I am expecting the output like tr for tour
Code:
#include <bits/stdc++.h>
using namespace std;
int main()
{
string word;
getline(cin, word);
transform(word.begin(), word.end(), word.begin(), ::tolower); // Converting uppercase to lowercase
for (int i = 0; i < word.length(); i++)
{
if (word[i] == 'a' || word[i] == 'e' || word[i] == 'i' || word[i] == 'o' || word[i] == 'u')
{
word.erase(word.begin() + i); // Removing specific character
}
}
cout << word << endl;
return 0;
}
How can I do that? Where is the problem in the code?
When you erase a character, your index i is still being incremented, which means you are skipping checking characters that appear right after a vowel.
You need to decrement i when you erase a character:
if (word[i] == 'a' || word[i] == 'e' || word[i] == 'i' || word[i] == 'o' || word[i] == 'u')
{
word.erase(word.begin() + i); // Removing specific character
--i; // make sure to check the next character
}
Here's a demo.
Also, please avoid the following 2 lines:
#include <bits/stdc++.h>
using namespace std;
They are dangerous and should not be used.
After erase, i++ is performed. That means one element is bypassed by the check.
Change the for loop to
for (int i = 0; i < word.length(); )
{
if (word[i] == 'a' || word[i] == 'e' || word[i] == 'i' || word[i] == 'o' || word[i] == 'u')
{
word.erase(word.begin() + i); // Removing specific character
}
else
{
i++; // increment when no erasion is performed
}
}
Here's how you can do it more easily:
#include <algorithm>
#include <array>
#include <cctype>
#include <iostream>
#include <string>
constexpr auto isVowel(unsigned char const ch) noexcept {
constexpr std::array<unsigned char, 10> vowels{
'a', 'e', 'i', 'o', 'u',
};
return std::find(vowels.begin(), vowels.end(), std::tolower(ch)) !=
vowels.end();
}
int main() {
std::string str = "Tour";
str.erase(std::remove_if(str.begin(), str.end(), isVowel), str.end());
std::cout << str << '\n';
}
Try online

Strings Code not Working

Using the C++ language, the function LetterChanges(str) takes the str parameter being passed and modifies it using the following algorithm.
Replace every letter in the string with the letter following it in the
alphabet (ie. c becomes d, z becomes a). Then capitalize every vowel
in this new string (a, e, i, o, u) and finally return this modified
string.
#include <iostream>
using namespace std;
string LetterChanges(string str) {
// code goes here
string str2 = "abcdefghijklmnopqrstuvwxyz";
int j;
for (int i = 0; str[i] != '\0'; i++) {
for (j = 0; str2[j] != '\0'; j++) {
if (str[i] == str2[j]) {
str[i] = str2[j + 1];
}
}
}
for (int i = 0; str[i] != '\0'; i++) {
if (str[i] == 'a') {
str[i] = 'A';
}
else if (str[i] == 'e') {
str[i] = 'E';
}
else if (str[i] == 'i') {
str[i] = 'I';
}
else if (str[i] == 'o') {
str[i] = 'O';
}
else if (str[i] == 'u') {
str[i] = 'U';
}
}
return str;
}
int main() {
// keep this function call here
cout << LetterChanges(gets(stdin));
return 0;
}
I am trying to run this code but it is not giving the desire output please help..
The Function
Let's start with your first loop:
for (int i = 0; str[i] != '\0'; i++) {
for (j = 0; str2[j] != '\0'; j++) {
if (str[i] == str2[j]) {
str[i] = str2[j + 1];
}
}
}
There are a couple things here. Firstly, we don't even need to deal with str2. Characters in C++ use ASCII encoding, meaning we can actually do something like str[i]++ to change an 'a' to a 'b' or an 'e' to an 'f', etc...
Also, I'd advise against using str[i] != '\0'. We're using the standard library strings instead of c-strings for a reason, so we might as well make our lives easier and use str.size(). Along these same lines, I'd suggest str.at(i) as opposed to str[i] as the former will do bounds checking for us.
Lastly, if you include cctype, then we can use the isalpha function to make sure we're only modifying alphabetic characters (no numbers or spaces, etc..).
Thus your first loop can become:
for (int i = 0; i < str.size(); i++) {
if(isalpha(str.at(i)){
if(str.at(i) == 'z') str.at(i) = 'a'; //special case
else str.at(i)++;
}
}
As far as your second loop, you don't even need it! We can actually incorporate everything straight into the first one. As long as we make sure to do the vowel modification after we've changed the individual letters.
A conversion from lowercase to uppercase can be done with some ASCII math as well. The difference between the lowercase and uppercase letters is 'A'-'a', so if we add that to any lowercase letter, it'll give us its uppercase version!
With all of this, we can modify your code to:
for (int i = 0; i < str.size(); i++) {
if(isalpha(str.at(i)){ //Make sure it's a letter!
if(str.at(i) == 'z') str.at(i) = 'a'; //special case
else str.at(i)++;
if(str.at(i) == 'a' | str.at(i) == 'e' | str.at(i) == 'i'
| str.at(i) == 'o' | str.at(i) == 'u') {
str.at(i) += 'A' - 'a';
}
}
Your Main
There's only one thing to fix here. Don't use gets for input. If you're looking for a single word, use the extraction operator, >>, or if you want a whole line, use getline.
string word, line;
getline(cin, line);
cin >> word;
cout << LetterChanges(line) << endl;
cout << LetterChanges(word) << endl;

Reverse an array without affecting special characters

Is it possible to reverse an array without affecting the special characters ? By special characters, I mean anything characters not included from 'a' to 'z' and 'A' to 'Z'. I am short of ideas to build the algorithm, I still haven't it figured out.
One simple solution would be to Simple Solution:
1) Create a temporary character array --> ex: myArr[].
2) Copy alphabetic characters from the given array to myArr[].
3) Reverse myArr[] using standard string reversal algorithm.
4) Now traverse input string and myArr in a single loop. Wherever there is alphabetic character is input string, replace it with current character of myArr[].
Little problem with above solution, it requires extra space and it does two traversals of input string.
You can reverse with one traversal and without extra space. Below is algorithm.
1) Let input string be 'str[]' and length of string be 'a'
2) l = 0, r = a-1
3) While l is smaller than r, do following
a) If str[l] is not an alphabetic character, do l++
b) Else If str[r] is not an alphabetic character, do r--
c) Else swap str[l] and str[r]
Here's a solution that will do it "in place" in one pass.
bool isspecial(char c)
{
if ((c >= 'a') && (c <= 'z')) return false;
if ((c >= 'A') && (c <= 'Z')) return false;
return true;
}
void rev(char* array, int N)
{
int i = 0; // i points to the first index of the array
int j = N - 1; // j points to the last index of the array
while (i < j)
{
if (isspecial(array[i]))
{
i++;
}
else if (isspecial(array[j]))
{
j--;
}
else
{
char tmp = array[i];
array[i] = array[j];
array[j] = tmp;
i++;
j--;
}
}
}
Console.WriteLine("enter any string");
string str = Console.ReadLine();
string[] revstr = new string[str.Length];
for (int i = 0; i < str.Length; i++)
{
int ch = Convert.ToInt16(str.ToLower()[i]);
if ((ch < 97 || ch > 122))
{
revstr[i] = str[i].ToString();
}
}
for (int k = str.Length - 1; k >= 0; k--)
{
int ch = Convert.ToInt16(str.ToLower()[k]);
if (!(ch < 97 || ch > 122))
{
for (int j = 0; j < str.Length; j++)
{
if (revstr[j] == null)
{
revstr[j] = str[k].ToString();
break;
}
}
}
}
for (int s = 0; s < revstr.Length; s++)
{
Console.Write(revstr[s]);
}
If you want the position of the special characters to remain the same and the rest of the string to be reversed then this should work -
#include <iostream>
using namespace std;
void swap(char& a, char& b)
{
char temp = a;
a = b;
b = temp;
}
int main()
{
string s = "Hell$o World";
for(int i = 0, j = s.length() -1;i < s.length()/2; i++, j--) {
while((s[i] <= 'a' && s[i] >= 'Z') || s[i] >= 'z' || s[i] <= 'A') {
i++;
}
while((s[j] <= 'a' && s[j] >= 'Z') || s[j] >= 'z' || s[j] <= 'A') {
j--;
}
swap(s[i], s[j]);
}
cout << s << endl; //dlro$W olleH
return 0;
}