I have a char array that has number 0-8 in it in char form
Board[0] = '0';
Board[1] = '1';
Board[2] = '2';
Board[3] = '3';
Board[4] = '4';
Board[5] = '5';
Board[6] = '6';
Board[7] = '7';
Board[8] = '8';
and some of them are changed to either an 'x' or an 'o' based on user input however I need to figure out a way so that I can tell the total number of them that aren't an 'x' or an 'o'.
What I mean is if say 4 of the 9 are either an 'x' or an 'o' I need to be able to get the fact that there are 5 left. I was attempting to use for each(char c in Board) and I got far enough to where I got it to list the chars that aren't an 'x' or an 'o' but I can't figure out how to get it to send how many are left to an int value. This is as far as I got.
for each(char c in Board)
{
if (c != 'x' && c != 'o')
{
}
}
You could try
auto n = std::count_if(Board, Board+9, std::isdigit);
You should define a counter that counts the number of these characters (by incrementing it):
int n = 0;
for (char c : Board)
{
if (c != 'x' && c != 'o')
{
n++; // increment n by 1
}
}
std::cout << n << '\n'; // use the result
You can use a combination of std::isdigit and std::count_if
#include <cctype> // for std::isdigit
#include <algorithm> // for std::count_if
int num = std::count_if(Board, Board+9, std::isdigit);
Assuming you don't just want any digit, and only those between 0 and 8 you could do this:
int count = 0;
for each(char c in Board)
{
if (c >= '0' && c <= '8')
{
count++;
}
}
cout << count << " are digits between 0 and 8 (inclusive)" << endl;
Related
I have an assignment that asks me to "Write a recursive function vowels(s,low,high) that returns the number of vowels in an input string s[]." We are also limited by "Do not use the C++ string type. Read the characters into an array one at a time using cin.get()." I think I solved the task at hand, but it doesnt compile so I am unsure. If anyone could assist me and show how to fix my error and any errors I've made towards my solution that would be great.
Here is my error message.
***main.cpp:24:37: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
vowelCount = vowels(s, low, high);**
Here is my code:
#include <iostream>
#include <cstring>
using namespace std;
int vowels(char, int, int);
int main()
{
char s[500];
int high,
vowelCount,
low = 0;
cout << "Enter a string of characters: ";
cin.get(s, 500);
high = strlen(s);
vowelCount = vowels(s, low, high);
cout << "The string contains " << vowelCount << " vowels." << endl;
return 0;
}
int vowels(char s[], int low, int high)
{
if (s[low] == 'a' || 'A' || 'e' || 'E' || 'i' || 'I' || 'o' || 'O' || 'u' || 'U') {
return 1 + vowels(s, low + 1, high - 1);
} else {
return vowels(s, low + 1, high - 1);
}
}
We are talking about a so called XY-Problem here.
The teacher wants to cover recursive functions. The vowel counting is just some noise. Unfortunately the given example is a bad one, because it could be implemented by far better with an iterative approach.
The recursion is just adding unnecessary time and space complexity. So, the performance is worse compared to a simple loop in all cases.
If the teacher wants that you learn about recursion, you may want to first look at this description or that more practical example.
After having read this, you will understand that a loop can be simply converted into a recursive function.
I am not sure, why there is a "low" and a "high" parameter. Maybe because of the usage of C-strings stored in a char array (what is nonsense in C++). I doubt that 2 self calls should be established and the function should walk from the begin and the end of the string to the middle. That would even further reduce the performance. So, let us assume the standard case.
Next to your problem with the comparison. What you have written is wrong. The correct comparison in C++ would be:
if ((s[low] == 'a') || (s[low] == 'A') || (s[low] == 'e') ||
(s[low] == 'E') || (s[low] == 'i') || (s[low] == 'I') ||
(s[low] == 'o') || (s[low] == 'O') || (s[low] == 'u') ||
(s[low] == 'U'))
Of course, nobody would write such a long statement, because you can simply calculate, without any comparison, if an ASCII character is a vowel. You could simply write:
if (std::isalpha(s[low]) && ((0x208222 >> (s[low] & 0x1f)) & 1))
and thats it. If you are interested, I can explain the theory later, but not needed for this example.
Then, next, your recursive function is dangerously wrong, because it does not have an end condition. it will run forever or until the stack overflows.
So, you need to rework that, It could be done like this:
#include <iostream>
#include <cstring>
using namespace std;
int vowels(char[], int, int);
int main()
{
char s[500];
int high,
vowelCount,
low = 0;
cout << "Enter a string of characters: ";
cin.get(s, 500);
high = strlen(s);
vowelCount = vowels(s, low, high);
cout << "The string contains " << vowelCount << " vowels." << endl;
return 0;
}
int vowels(char s[], int low, int high)
{
int sum = 0;
if (low != high) {
if ((s[low] == 'a') || (s[low] == 'A') || (s[low] == 'e') ||
(s[low] == 'E') || (s[low] == 'i') || (s[low] == 'I') ||
(s[low] == 'o') || (s[low] == 'O') || (s[low] == 'u') ||
(s[low] == 'U'))
{
++sum;
}
sum += vowels(s,low+1,high);
}
return sum;
}
If we go a little bit more into the direction of C++ and use meaningful variable names and comments, then we could come up with that:
#include <iostream>
#include <cstring>
// A recursive function to count the vowels in a rang of a text
int countVowelsRecursive(char textToEvaluate[], unsigned int startPositionForEvaluation, unsigned int endPositionOfText)
{
// Here we will store the number of vowels. We will use tail recursion
// So, the overall calculation will be done at the end
unsigned int numberOfVowelsInThisRecursion = 0u;
// Now we are evaluating this character from the text
const char currentChar = textToEvaluate[startPositionForEvaluation];
// Check, for the end of recursion condition
if (startPositionForEvaluation != endPositionOfText) {
// Check, if it is a vowel
if ((currentChar == 'a') || (currentChar == 'A') || (currentChar == 'e') ||
(currentChar == 'E') || (currentChar == 'i') || (currentChar == 'I') ||
(currentChar == 'o') || (currentChar == 'O') || (currentChar == 'u') ||
(currentChar == 'U'))
{
// Vowel found. Increase counter by one
++numberOfVowelsInThisRecursion;
}
// Tail recursion. Self call, starting at next position of the string
numberOfVowelsInThisRecursion +=
countVowelsRecursive(textToEvaluate,startPositionForEvaluation + 1, endPositionOfText);
}
// This will be the final result
return numberOfVowelsInThisRecursion;
}
// We will allow a maximal input text length like this
constexpr unsigned int MaxTextLength = 500u;
// Driver code / test function
int main()
{
// Here we will store the text from the user
char text[MaxTextLength]{};
// Give instructions and get the text
std::cout << "Enter a string of characters: ";
std::cin.get(text, MaxTextLength);
// Set text parameters for the evaluation
unsigned int startOfText = 0u;
unsigned int endOfText = static_cast<unsigned int>(strlen(text));
// Calculate the vowels
unsigned int vowelCount = countVowelsRecursive(text, startOfText, endOfText);
// Show result to user
std::cout << "The string contains " << vowelCount << " vowels." << std::endl;
return 0;
}
And if we would be allowed to use C++ then we would write:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
// Give instructions and get the text
std::cout << "\nEnter a text:\n";
if (std::string text{}; std::getline(std::cin, text))
// Show result to user
std::cout << "\n\nThe string contains "
<< std::count_if(text.begin(), text.end(), [](const char c){ return std::isalpha(c) && ((0x208222 >> (c & 0x1f)) & 1);})
<< " vowels.\n";
return 0;
}
Have fun . . .
I have been asked to write a code to print only consonants using a dynamic array. I wrote a code to do that but it prints exactly the input without canceling out the vowels.
#include <iostream>
#include<string>
using namespace std;
int main()
{
int len,i;
cin>>len;
char* pArray=new char[len];
char ch[len];
for(i=0;i<len;i++)
cin>>ch[i];
for(i =0;i<len;i++){
if(ch[i]=='a' && ch[i]=='e' && ch[i]=='i' && ch[i]=='o' && ch[i]=='u')
break;
else
pArray[i]=ch[i];
}
for( i=0;i<len;i++)
cout<<(pArray[i]);
return 0;
}
If I write the input ample, it should print only mpl.
Your program isn't working because of logic error. You have used && operator between each logical expression. So, whenever the compiler come across a character it checks whether the character is 'a' and 'e' and 'i' and 'o' and 'u', which is obviously not possible simultaneously at the same time. Use "||" operator instead of "&&". Also for entering character in pArray you need to define another integer for its index .
int k=0;
for(i =0;i<len;i++){
if(ch[i]=='a' || ch[i]=='e' || ch[i]=='i' || ch[i]=='o' || ch[i]=='u')
break;
else
{pArray[k]=ch[i]; k++;}
doing
for(i =0;i<len;i++){
if(ch[i]=='a' && ch[i]=='e' && ch[i]=='i' && ch[i]=='o' && ch[i]=='u')
break;
else
pArray[i]=ch[i];
}
the test ch[i]=='a' && ch[i]=='e' && ch[i]=='i' && ch[i]=='o' && ch[i]=='u' is always false because a character cannot be several at the same time.
you also need a dedicated index to write in pArray and not print after based on len but that additional index.
Also check cin>>len; success (and other use of >>) else you do with len is 0 and none of the next read success because you do not clear the error flag nor bypass the invalid input.
Note also there are not only vowel and consonant, so when a character is not vowel that does not means it is a consonant, what must be done for other characters ?
Do not use variable length arrays as you did for ch.
Out of that, why are you using array of characters rather than std::string, is it required by statement ?
based on your code minimal changes also managing uppercase character can be :
#include <iostream>
#include <ctype.h>
using namespace std;
int main()
{
int len;
if (!(cin>>len))
cerr << "len is not a number" << endl;
else if (len <= 0)
cerr << "len must be > 0" << endl;
else {
char* pArray = new char[len];
char* ch = new char[len];
int i;
for (i=0;i<len;i++){
if (!(cin>>ch[i])) {
cerr << "EOF, abort" << endl;
return -1;
}
if (!isalpha(ch[i])) {
cerr << "invalid character, abort" << endl;
return -1;
}
}
int j = 0;
for(i =0;i<len;i++) {
switch (ch[i]) {
case 'a':
case 'A':
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U':
case 'y': // is vowel no ?
case 'Y': // is vowel no ?
break;
default:
// suppose only consonant and vowel
pArray[j++]=ch[i];
}
}
for( i=0;i<j;i++)
cout<<(pArray[i]);
cout << endl;
}
return 0;
}
Compilation and execution :
pi#raspberrypi:/tmp $ g++ -Wall c.cc
pi#raspberrypi:/tmp $ ./a.out
5
ample
mpl
pi#raspberrypi:/tmp $
There's a few mistakes in your code. I'm feeling generous, see how you get on with this
int main()
{
// read the word
int length;
cin >> length;
char* word = new char[length];
for (int i = 0; i < length; ++i)
cin >> word[i];
// allocate enough space for the word without vowels
char* no_vowels = new char[length];
// copy the non-vowels
int no_vowels_length = 0;
for (int i = 0; i < length; ++i)
{
if (word[i] != 'a' && word[i] != 'e' && word[i] != 'i' && word[i] != 'o' && word[i] != 'u')
{
// found a non-vowel, copy it to the end of the no-vowel word
no_vowels[no_vowels_length] = word[i];
// and increase the length of the no vowel word
++no_vowels_length;
}
}
// write out the word without vowels
for (int i = 0; i < no_vowels_length; ++i)
cout << no_vowels[i];
}
I think the idea you are missing is that you need two variables for the lengths of your two different strings
Quickly fixing the code inline:
every warning(1) error(4) is commented inline.
#include <iostream>
#include<string>
using namespace std;
int main()
{
int len, i;
cin >> len;
char* pArray = new char[len];
char* ch = new char[len];
for (i = 0; i < len; i++)
cin >> ch[i];
//WARNING: please note that pArray NOR ch isn't NULL terminated
int j = 0; //ERROR 1: you need to count the inserted char
for (i = 0; i < len; i++) {
//ERROR 2: you need an OR in order to check for vowels, not an AND
if (ch[i] == 'a' || ch[i] == 'e' || ch[i] == 'i' || ch[i] == 'o' || ch[i] == 'u')
//ERROR 3: if found, do not break, instead skip the vowels...
continue;
else
pArray[j++] = ch[i]; //ERROR 1bis: so you increment the j every time you insert a char
}
for (i = 0; i < j; i++) //ERROR 4: print out only the added lettere, indeed pArray is longer than needed (space for further improvement?)
cout << (pArray[i]);
return 0;
}
Hope it helps,
Stefano
I believe there is a hole in your logic. IMHO, you can't have the same index for the ch (source) array and the pArray (target or destination) array.
Draw out the source and target arrays:
Source (example):
+---+---+---+---+---+
| H | e | l | l | o |
+---+---+---+---+---+
Target:
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
After ignoring the e, your Source will be pointing at the first 'l' and your target will be pointing at the 3rd slot in pArray:
Source (example):
+---+---+---+---+---+
| H | e | l | l | o |
+---+---+---+---+---+
0 1 2 3 4
Target:
+---+---+---+---+---+
| H | | l | | |
+---+---+---+---+---+
0 1 2 3 4
In the simple version you will need to have one index that represents the "next" available slot in the target array, and one index that represents the current letter in the source array.
(Or you could use another pointer to the target array and increment that)
char * p_target_slot = pArray;
int target_index = 0;
for(i =0;i<len;i++)
{
if( ch[i]=='a'
|| ch[i]=='e'
|| ch[i]=='i'
|| ch[i]=='o'
|| ch[i]=='u')
continue;
else
{
*p_target_slot++ = ch[i];
// Or you can use this:
pArray[target_index] = ch[i];
++target_index;
}
}
I have an assignment where I have to make a program that allows a person to input a seven letter word and converts it to a telephone number (1-800-PAINTER to 1-800-724-6837 for example). I'm trying to make each letter convert to a specific number to be outputted to the user, with each letter corresponding to its number on a telephone keypad (so a, A, b, B or c, C equals 1, i.e, more info: https://en.wikipedia.org/wiki/Telephone_keypad).
Currently I have it set up so that each letter of the input word represents a char variable of one, two, three, four, five, six, or seven respectively. Then, using switch and if statements, the idea was to convert a char to an int variable of xtwo = 2, xthree = 3, etc. This isn't working however. Is there a better way to do this?
Example of code (up to first switch, though mostly it's a repeating pattern like so):
int main()
{
char one, two, three, four, five, six, seven;
cout << "Enter seven letter word (1-800-***-****): " << "\n";
cin >> one >> two >> three >> four >> five >> six >> seven;
int xtwo = 2; int xthree = 3; int xfour = 4; int xfive = 5; int xsix = 6; int xseven = 7; int xeight = 8;
int xnine = 9;
switch (one)
{
case 1:
if (one == 'a' || one == 'b' || one == 'c' || one == 'A' || one == 'B' || one == 'C')
{
one = xtwo;
}
break;
case 2:
if (one == 'd' || one == 'e' || one == 'f' || one == 'D' || one == 'E' || one == 'F')
{
one = xthree;
}
break;
case 3:
if (one == 'g' || one == 'h' || one == 'l' || one == 'G' || one == 'H' || one == 'L')
{
one = xfour;
}
break;
case 4:
if (one == 'j' || one == 'k' || one == 'l' || one == 'J' || one == 'K' || one == 'L')
{
one = xfive;
}
break;
case 5:
if (one == 'm' || one == 'n' || one == 'o' || one == 'M' || one == 'N' || one == 'O')
{
one = xsix;
}
break;
case 6:
if (one == 'p' || one == 'q' || one == 'r' || one == 's' || one == 'P' || one == 'Q' || one == 'R' || one == 'S')
{
one = xseven;
}
break;
case 7:
if (one == 't' || one == 'u' || one == 'v' || one == 'T' || one == 'U' || one == 'V')
{
one = xeight;
}
break;
case 8:
if (one == 'w' || one == 'x' || one == 'y' || one == 'z' || one == 'W' || one == 'X' || one == 'Y' || one == 'Z')
{
one = xnine;
}
break;
}
So, in essence, how can a char variable of a letter be converted to a specific int variable?
You could use a std::map.
For example, you could have
std::map<char,int> char_to_dig {
{'a',1}, {'b',1}, {'c',1},
{'d',2}, {'e',2}, {'f',2}
};
Then
char_to_dig['a']
will give you 1.
Alternatively, you could write a function that does the mapping. Something along the lines of this:
int char_to_dig(char c) {
static const char _c[] = "abcdefghi";
static const int _i[] = { 1,1,1,2,2,2,3,3,3 };
for (unsigned i=0; i<9; ++i) {
if (_c[i]==c) return _i[i];
}
return -1; // some value to signal error
}
Or, instead of using arrays, you could perform arithmetic on the chars (since they are just small integers).
int char_to_dig(char c) {
c = std::toupper(c);
if (c < 'A' || c > 'Z') return -1;
if (c == 'Z') return 9;
if (c > 'R') --c;
return ((c-'A')/3)+2;
}
This will give you numbers like on this pad:
Apparently, there's been a similar code golf question.
It has been years since I wrote any c/c++ code and I don't even have a compiler installed to test with .. but this should get you started on the right track
Check functions and syntax...all out of my head. Needs checking.
//
int numArray[7];
char inputStr[10];
cout << " give me 7 characters";
cin >> input;
/*
use a for loop to read the string letter by letter (a string in c is an
array of characters)
convert the characters to uppercase
fall through case statements for each group of letters
assing value to output array to do wiht as you like.
*/
for(i=0; i < 7; i++){
inputStr[i] = toupper(inputStr[i]);
switch(input[i]){
case 'A':
case 'B':
case 'C':
numArray[i] = 2;
break;
case 'D':
case 'E':
case 'F':
numArray[i] = 3;
break;
and so on and so foth....
}
}
I'm working on a Caesar Cipher program for an assignment and I have the general understanding planned out, but my function for determining the decipher key is unnecessarily long and messy.
while(inFile().peek != EOF){
inFile.get(character);
if (character = 'a'|| 'A')
{ aCount++; }
else if (character = 'b' || 'B')
{ bCount++; }
so on and so on.
What way, if it's possible, can I turn this into an array?
You can use the following code:
int count [26] = {0};
while(inFile().peek != EOF){
inFile.get(character);
if (int (character) >=65 || int (character) <=90)
{ count [(int (character)) - 65] ++; }
else if (int (character) >=97 || int (character) <=122)
{ count [(int (character)) - 97] ++; }
}
P.S. This is checking for the ASCII value of each character and then increment its respective element in the array of all characters, having 0 index for A/a and 1 for B/b and so on.
Hope this helps...
P.S. - There was an error in your code, = is an assignment operator and == is a conditional operator and you do not assign value in if statement, you check for condition... So always use == to check for equality...
You can use an array in the following manner
int letterCount['z'] = {0}; //z is the highest letter in the uppercase/lowercase alphabet
while(inFile().peek != EOF){
inFile.get(character);
if (character > 'A' && character < 'z')
letterCount[character]++;
}
You can also use a hashmap like this
#include <unordered_map>
std::unordered_map<char,int> charMap;
while(inFile().peek != EOF){
inFile.get(character);
if (charMap.find(character) == charMap.end())
charMap[character] = 1;
else
charMap[character] = charMap[character] + 1;
}
In case you do not know, a hashmap functions as an array, where the index can be any class you like, as long as it implements a hash function.
I am trying to check if each character of a string in a string array is equal to any of the five vowels. However, when I test it to see when a vowel character in a string is equal to 'vowel', I get that they are not equal. The problem with the code is the bolded part below. Also, when I try to do "a" || "e" || "i" || "o" || "u", I get the error that ISO C++ forbids comparison between pointer and integer. How can I be able to check if they are equal? Thank you for your time.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <cmath>
#include <cstdlib>
using namespace std;
int l, c; //l is amount of letters in password, c is amount of letters being inputted
char letters[1000000]; //the letters being inputted
vector <string> pass; //string vector of the stored passwords
void rec(string current, int index, int x){ //determining all possible passwords
if (index >= 4){
pass.push_back(current);
}
else{
for (int i=0; i<c; i++){
if (x<i){
int old;
old = x;
x = i;
rec(current + letters[i], index+1, x);
x = old;
}
}
}
}
int main (int argc, char ** argv)
{
cin >> l >> c;
int x = -1;
for (int i=0; i<c ;i++){
cin >> letters[i];
}
sort(letters, letters + c); //sorted from least to greatest
rec("", 0, x);
for (int i=0; i<pass.size(); i++){
int vl=0; //number of vowels
int nvl=0; //number of non-vowels (consonants)
for (int j=0; j<l; j++){
**if (pass.at(0)[j] == 'a' || 'e' || 'i' || 'o' || 'u'){**
vl++;
}
else{
nvl++;
}
if (j == l-1){
if (vl >= 1 && nvl >= 2){
cout << pass.at(0) << endl;
}
}
}
}
return 0;
}
In C++, X || Y means:
Test if X is true. If so, result of whole expression is true
Otherwise, test if Y is true. Result of Y is result of expression.
So your code:
pass.at(0)[j] == 'a' || 'e'
(omitting for now the i etc. as they don't change anything).
We tested pass.at(0)[j] == 'a' . That was false, so now we test 'e'. Not that you did NOT test pass.at(0)[j] == 'e'. You just tested 'e'. This is the same as testing 'e' != 0, which is true. So your expression evaluates to true at this point (and does not go onto check 'i' etc.)
You probably intended to test whether pass.at(0)[j] held any of the values 'a', 'e', etc. If so then one way to encode that is:
if ( std::strchr("aeiou", pass.at(0)[j]) )
You should make sure j < strlen(pass.at(0)) before doing this though; using [] to generate an out of bounds index causes undefined behaviour.
Because you are using the || wrong. The part either side of || is a "true or false" expressin in itself, so you need something like:
if (pass.at(0)[j] == 'a' || pass.at(0)[j] == 'e' ... )
Otherwise, the expression is always true, since || is true if the expression on left or right is true, and 'e' is true by not being zero.
This does not do what you think...
(pass.at(0)[j] == 'a' || 'e' || 'i' || 'o' || 'u')
You need to explicitly compare,
char t = pass.at(0)[j];
if (t == 'a' || t == 'e' || t == 'i' || t == 'o' || t == 'u') {