I recently have been building a program where:
A user is asked to enter a number that will represent the size of a character array.
Then they are asked whether they will want the program to fill the values automatically, or they could press M so they could enter the values manually. They may only enter a-zA-Z values, or they will see an error.
At the end of the program, I am required to count every duplicate value and display it, for example:
An array of 5 characters consists of A;A;A;F;G;
The output should be something like:
A - 3
F - 1
G - 1
I could do this easily, however, the teacher said I may not use an additional array, but I could make a good use of a few more variables and I also can't use a switch element. I'm totally lost and I can't find a solution. I've added the code down below. I have done everything, but the counting part.
#pragma hdrstop
#pragma argsused
#include <tchar.h>
#include <iostream.h>
#include <conio.h>
#include <math.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
void main() {
int n, i = 0;
char masiva_izvele, array[100], masiva_burts;
cout << "Enter array size: ";
cin >> n;
clrscr();
cout << "You chose an array of size " << n << endl;
cout << "\nPress M to enter array values manually\nPress A so the program could do it for you.\n\n";
cout << "Your choice (M/A): ";
cin >> masiva_izvele;
if (masiva_izvele == 'M' || masiva_izvele == 'm') {
clrscr();
for (i = 0; i < n; i++) {
do {
cout << "Enter " << i + 1 << " array element: ";
flushall();
cin >> masiva_burts;
cout << endl << int(masiva_burts);
if (isalpha(masiva_burts)) {
clrscr();
array[i] = masiva_burts;
}
else {
clrscr();
cout << "Unacceptable value, please enter a value from the alphabet!\n\n";
}
}
while (!isalpha(masiva_burts));
}
}
else if (masiva_izvele == 'A' || masiva_izvele == 'a') {
clrscr();
for (i = 0; i < n; i++) {
array[i] = rand() % 25 + 65;
}
}
clrscr();
cout << "Masivs ir izveidots! \nArray size is " << n <<
"\nArray consists of following elements:\n\n";
for (i = 0; i < n; i++) {
cout << array[i] << "\t";
}
cout << "\n\nPress any key to view the amount of every element in array.";
//The whole thing I miss goes here, teacher said I would need two for loops but I can't seem to find the solution.
getch();
}
I would be very thankful for a solution so I could move on and forgive my C++ amateur-ness as I've picked this language up just a few days ago.
Thanks.
EDIT: Edited title to suit the actual problem, as suggested in comments.
One possible way is to sort the array, and then iterate over it counting the current letter. When the letter changes (for example from 'A' to 'F' as in your example) print the letter and the count. Reset the counter and continue counting the next character.
The main loop should run foreach character in your string.
The secondary loop should run each time the main "passes by" to check if the current letter is in array. If it's there, then ++.
Add the array char chars[52] and count chars in this array. Then print out chars corresponding to the array, which count is more than 1.
std::unordered_map<char, int> chars;
...
char c = ...;
if ('A' <= c && c <= 'Z')
++chars[c];
else if ('a' <= c && c <= 'z')
++chars[c];
else
// unexpected char
...
for (const auto p : chars)
std::cout << p.first << ": " << p.second << " ";
Assuming upper and lower case letters are considered to be equal (otherwise, you need an array twice the size as the one proposed:
std::array<unsigned int, 26> counts; //!!!
// get number of characters to read
for(unsigned int i = 0; i < charactersToRead; ++i)
{
char c; // get a random value or read from console
// range check, calculate value in range [0; 25] from letter...
// now the trick: just do not store the value in an array,
// evaluate it d i r e c t l y instead:
++counts[c];
}
// no a d d i t i o n a l array so far...
char c = 'a';
for(auto n : counts)
{
if(n > 0) // this can happen now...
{
// output c and n appropriately!
}
++c; // only works on character sets without gaps in between [a; z]!
// special handling required if upper and lower case not considered equal!
}
Side note: (see CiaPan's comment to the question): If only true duplicates to be counted, must be if(n > 1) within last loop!
Related
I'm trying to make a quiz checker where the user will input their answer and it will automatically check in the array. Any tips?
Here is my code:
int main()
{
string aswer[] = { "D", "C", "D", "D", "A"); //
char input[5];
int counter ;
int points = 0;
cout << "Welcome and Good luck!\n";
for (counter = 0; counter < 5; counter++) {
cout << counter << " Choose from letters A-D: \n";
cin >> input;
}
for (int i = 0; i < 5; ++i) {
cout << "\n you enter " << input[i] << endl;
}
foreach (char item in answer){
foreach (char item1 in inputs){
If (item == item1){
points = points +1
}
}
}
return 0;
}
Tips -- be consistent choosing storage. If you are using a std::string for the answer (not the erroneous array of std::string shown), then use a std::string for input as well. But if you must use a POA (plain old array), that's fine for educational purposes -- you just lack all auto-memory management and bounds protections.
You initialize a std::basic_string as:
std::string answer { "DCDDA" }; /* initialize string (not array of strings) */
(note: the use of std:: namespace identifier. See Why is “using namespace std;” considered bad practice?)
Don't use Magic Numbers in your code. The 5 you stick in your array declaration and in your loop limit is a Magic Number. Instead,
#define NCHAR 5 /* if you need a constant, #define one (or more) */
...
char input[NCHAR]; /* array of 5 char (why not string?) */
...
for (int i = 0; i < NCHAR; i++) { /* loop taking input */
When you loop taking input, validate every input. The user may well generate a manual EOF to cancel input with Ctrl+d (or Ctrl+z on windows). Only increment the count of characters stored after you have validated the input, e.g.
int counter = 0, points = 0; /* counter and points, initialized zero */
std::cout << "Welcome and Good luck!\n\n";
for (int i = 0; i < NCHAR; i++) { /* loop taking input */
std::cout << " " << i << ". Choose from letters A-D: ";
if (std::cin >> input[i]) /* validate input */
counter++; /* only increment on successful input */
}
For your output, understand the difference between using '\n' and std::endl, C++: “std::endl” vs “\n”.
When you have items stored in a container (such as std::string), you can use a Range-based for loop (since C++11) to loop over each item in the container. To loop over your stored input, you must limit the loop to the number of elements successfully read as input. Use the same counter as your comparison limit, e.g.
for (auto& item : answer) /* range based for-loop over chars in string */
for (int i = 0; i < counter; i++) /* loop over counter chars in array */
if (item == input[i]) /* if the item matches the input char */
points += 1; /* add point */
Putting it altogether, you would have:
#include <iostream>
#include <string>
#define NCHAR 5 /* if you need a constant, #define one (or more) */
int main()
{
std::string answer { "DCDDA" }; /* initialize string (not array of strings) */
char input[NCHAR]; /* array of 5 char (why not string?) */
int counter = 0, points = 0; /* counter and points, initialized zero */
std::cout << "Welcome and Good luck!\n\n";
for (int i = 0; i < NCHAR; i++) { /* loop taking input */
std::cout << " " << i << ". Choose from letters A-D: ";
if (std::cin >> input[i]) /* validate input */
counter++; /* only increment on successful input */
}
std::cout << "\nYou entered:\n"; /* output stored values */
for (int i = 0; i < counter; i++) /* looping only 0 to counter */
std::cout << " input[" << i << "] : " << input[i] << '\n';
for (auto& item : answer) /* range based for-loop over chars in string */
for (int i = 0; i < counter; i++) /* loop over counter chars in array */
if (item == input[i]) /* if the item matches the input char */
points += 1; /* add point */
std::cout << "\nTotal points: " << points << '\n'; /* output total points */
}
Example Use/Output
$ ./bin/points
Welcome and Good luck!
0. Choose from letters A-D: A
1. Choose from letters A-D: B
2. Choose from letters A-D: C
3. Choose from letters A-D: D
4. Choose from letters A-D: E
You entered:
input[0] : A
input[1] : B
input[2] : C
input[3] : D
input[4] : E
Total points: 5
Checking maximum points if all characters match:
$ ./bin/points
Welcome and Good luck!
0. Choose from letters A-D: D
1. Choose from letters A-D: C
2. Choose from letters A-D: D
3. Choose from letters A-D: D
4. Choose from letters A-D: A
You entered:
input[0] : D
input[1] : C
input[2] : D
input[3] : D
input[4] : A
Total points: 11
Look things over and let me know if you have questions.
Written some algorithm to find out if a given word is a palindrome. But one of my variables (counter) seems not updating when I debugged and I can't figure out what is wrong with it. I may be wrong though... any help will be needed as I don's wanna copy some code online blindly.
Below is the code:
#include <iostream>
#include <cstring>
using namespace std;
int main(){
//take input
string input;
cout << "Enter your word: ";
cin >> input;
//initialize arrays and variables
int counter = 0, k = 0;
int char_length = input.length();
char characters[char_length];
strcpy(characters, input.c_str());//copy the string into char array
//index of character at the midpoint of the character array
int middle = (char_length-1)/2;
int booleans[middle]; //to keep 1's and 0's
//check the characters
int m = 0, n = char_length-1;
while(m < middle && n > middle){
if(characters[m] == characters[n]){
booleans[k] = 1;
} else {
booleans[k] = 0;
}
k++;
m++;
n--;
}
//count number of 1's (true for being equal) in the booleans array
for(int i = 0; i < sizeof(booleans)/sizeof(booleans[0])-1; i++){
counter += booleans[i];
}
//compare 1's with size of array
if(counter == middle){
cout << input << " is a Palindrome!" << endl;
} else {
cout << input << " is not a Palindrome!" << endl;
}
return 0;
}
Brother it seems difficult to understand what your question is and what code you are typing. I am not very much experienced but according to me palindrome is a very very simple and easy program and i would have wrote it as:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char str1[20], str2[20];
int i, j, len = 0, flag = 0;
cout << "Enter the string : ";
gets(str1);
len = strlen(str1) - 1;
for (i = len, j = 0; i >= 0 ; i--, j++)
str2[j] = str1[i];
if (strcmp(str1, str2))
flag = 1;
if (flag == 1)
cout << str1 << " is not a palindrome";
else
cout << str1 << " is a palindrome";
return 0;
}
It will work in every case you can try.
If you get a mismatch i.e. (characters[m] == characters[n]) is false then you do not have a palindrome. You can break the loop at that point, returning false as your result. You do not do that, instead you carry on testing when the result is already known. I would do something like:
// Check the characters.
int lo = 0;
int hi = char_length - 1;
int result = true; // Prefer "true" to 1 for better readability.
while (lo < hi) { // Loop terminates when lo and hi meet or cross.
if(characters[lo] != characters[hi]) {
// Mismatched characters so not a palindrome.
result = false;
break;
}
lo++;
hi--;
}
I have made a few stylistic improvements as well as cleaning up the logic. You were doing too much work to solve the problem.
As an aside, you do not need to check when the two pointers lo and hi are equal, because then they are both pointing to the middle character of a word with an odd number of letters. Since that character must be equal to itself there is not need to test. Hence the < in the loop condition rather than <=.
Existing Code does not work for Palindromes of Odd Length because of
for(int i = 0; i < sizeof(booleans)/sizeof(booleans[0])-1; i++)
Either use i<=sizeof(booleans)/sizeof(booleans[0])-1; or i<sizeof(booleans)/sizeof(booleans[0]);.
Currently, you are not counting the comparison of character[middle-1] and character[middle+1].
For palindromes of even length, you will have to change your logic a bit because even length palindromes don't have a defined middle point.
#include <iostream>
#include <cstring>
using namespace std;
int main(){
//take input
string input;
cout << "Enter your word: ";
cin >> input;
//initialize arrays and variables
int counter = 0, k = 0;
int char_length = input.length();
char characters[char_length];
strcpy(characters, input.c_str());//copy the string into char array
//index of character at the midpoint of the character array
int middle = (char_length+1)/2;
int booleans[middle]; //to keep 1's and 0's
//check the characters
int m = 0, n = char_length-1;
while(m<=n){
if(characters[m] == characters[n]){
booleans[k] = 1;
} else {
booleans[k] = 0;
}
k++;
m++;
n--;
}
//count number of 1's (true for being equal) in the booleans array
for(int i = 0; i < sizeof(booleans)/sizeof(booleans[0]); i++){
counter += booleans[i];
}
cout<<counter<<" "<<middle<<endl;
//compare 1's with size of array
if(counter == middle){
cout << input << " is a Palindrome!" << endl;
} else {
cout << input << " is not a Palindrome!" << endl;
}
return 0;
}
Over here the size of the boolean array is (length+1)/2,
For string s like abcba it will be of length 3.
This corresponds to a comparison between a a, b b and c c. Since the middle element is the same, the condition is always true for that case.
Moreover, the concept of middle is removed and the pointers are asked to move until they cross each other.
I am trying to find the number of times each letter of the alphabet shows up in a randomized string that the user creates. I have all the code, minus the portion that would count each time a character is found. I have tried to use a couple of for...else loops to figure this out, but maybe I am just not learned to do it correctly, I keep either getting errors or a blank space under the rest of the output.
What I want is for the output to look like this:
A B C D E F G...
1 2 5 7 0 9 2...
Here is my code and my output so far:
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <map>
using namespace std;
int main() {
int i=0, n;
char alphabet[26];
char c;
char RandomStringArray [100];
srand(time(0));
cout <<"How many letters do you want in your random string (no less than 0, no more than 100): ";
cin >> n;
for (int i=0; i<=25; i++)
alphabet[i] = 'a' + i;
while(i<n) {
int temp = rand() % 26;
RandomStringArray[i] = alphabet[temp];
i++;
}
for(i=0; i<n; i++)
cout<<RandomStringArray[i];
cout<<"\n\n";
/*for(c = 'A'; c <= 'Z'; ++c)
cout<<" "<<c;
cout<<"\n";
*/
map<char,size_t> char_counts;
for (int i = 0; i < n; ++i) ++char_counts[RandomStringArray[i]];{
for (char ch :: alphabet) std::cout << ch << ' ';{
std::cout << '\n';
}
for (char ch :: alphabet) std::cout << char_counts[ch] <<'';{
std::cout << '\n';
}
}
}
std::unordered_map is good for this sort of thing. It's similar to the array approach of holding counts for each character but is more convenient to use, especially when the character ranges you're interested in are non-contiguous.
When you index a std::unordered_map the mapped value will be returned by reference, so you just increment it. If it doesn't exist it's created and default initialized (zero initialized for integer types).
So all you need to do is:
std::unordered_map<char, std::size_t> char_counts;
for (int i = 0; i < n; ++i) ++char_counts[RandomStringArray[i]];
After this, char_counts holds the total occurrence counts for all characters in the string. e.g. char_counts['a'] is the number of occurrences of 'a'.
Then to print them all out you could do:
for (char ch : alphabet) std::cout << ch << ' ';
std::cout << '\n';
for (char ch : alphabet) std::cout << char_counts[ch] << ' ';
std::cout << '\n';
I've been struggling with a homework assignment that counts the amount of instances a uppercase letters, lowercase letters, and numbers in a string. appears in a string.
I'm using a one-dimensional array with a constant size of 132 to store the entered string, and I need to use two functions. One needs to count the amount of letter occurrences in the string and the other function will execute the output something similar to above. I'm struggling most with the letter counting aspect of the program itself.
Currently, this is what my current homework resembles for the most part. It's a work in progress (of course) so errors in the code are very likely.
void LetterCount(char c_input[], int l_count)
{
// code to count letters
}
void CountOut(//not sure what should go here yet until counting gets figured out)
{
// code that handles output
}
int main()
{
const int SIZE = 132;
char CharInput[SIZE];
int LetterCount = 0;
cout << "Enter a string of up to 132 characters in size: ";
cin.getline(CharInput, SIZE);
cout << "You entered: " << CharInput << endl;
Count(CharInput);
CountOut(//not sure what goes here yet);
return 0;
}
The output would look something like:
a - 2
b - 1
c - 1
d - 0
e - 1
etc...
I've tried some experimentation with for loops to count the letters and have seen some examples of the function gcount(), but I haven't gotten anything to work. Does anyone have a suggestion as to how I would count the letters in an inputted string?
map is a very efficient data structure here
#include <iostream>
#include <map>
using namespace std;
int main(){
string str = "a boy caught 2 fireflies";
map<char, int> str_map;
for(auto x : str) ++str_map[x];
for(auto x : str_map) cout << x.first << ' ' << x.second << '\n';
}
What you want is to build a simple histogram, and it's pretty easy to do. Since what you're looking at is chars, and there can be 256 possible values of an 8-bit char (in practice your input string probably uses less, but we'll be conservative here because memory is cheap), you'll want to start with an array of 256 ints, all of them initialized to zero. Then iterate over the chars your string, and for each char in your string, use that char-value as an offset into the array(*), and simply increment that item in the array.
When you're done, all that remains is to iterate over the ints in the array and print out the ones that are non-zero, and you're done.
(*) you may want to cast the char to unsigned char before using it as an offset into the array, just to avoid any chance of it being interpreted as a negative array-index, which would result in undefined behavior (this is only an issue if your input string contains ASCII characters 128 and higher, so it may not matter in your case, but it's always good form to make code that does the right thing in all cases if you can)
As Jeremy frisner said you're building a histogram, but I disagree with the types used.
You'll want to declare your histogram like so:
size_t histogram[sizeof(char)*CHAR_BIT] = {0};
The size_t because you might overflow without it, and you need enough space if it's a nonstandard byte size.
As for printing it out. You should take a look at an ASCII table and examine which values you need to print out.
You could do it by comparing c-strings with other c-strings. But with chars and strings you can get errors like: "const *char cant be compared with strings". So you'll have to compare each c string(array) index with other c string indexes. In this program I use if statements to look for certain vowels. The way it works is that each "string alphabet_letter" is equal to it's respective lowercase and capital letters (for comparison). this is a very redundant way to do it and, if you want to count all total letters, perhaps you should try a different way, but this method doesn't use very complicated methods that require deeper understanding.
using namespace std;
int main(){
int vowel;
string A = "aA";
string E = "eE";
string I = "iI";
string O = "oO";
string U = "uU";
string str;
string str1;
bool userLength = true;
int restart = 0;
do{
cout << "Enter a string." <<endl;
getline(cin, str);
int VowelA = 0;
int VowelE = 0;
int VowelI = 0;
int VowelO = 0;
int VowelU = 0;
for(int x = 0; x < 100; x++){
if(restart == 1){
restart = 0;
x = 0;
}
if(A[0] == str[x]){
VowelA = VowelA + 1;
}
if(E[0] == str[x]){
VowelE = VowelE + 1;
}
if(I[0] == str[x]){
VowelI = VowelI + 1;
}
if(O[0] == str[x]){
VowelO = VowelO + 1;
}
if(U[0] == str[x]){
VowelU = VowelU + 1;
}
if(A[1] == str[x]){
VowelA = VowelA + 1;
}
if(E[1] == str[x]){
VowelE = VowelE + 1;
}
if(I[1] == str[x]){
VowelI = VowelI + 1;
}
if(O[1] == str[x]){
VowelO = VowelO + 1;
}
if(U[1] == str[x]){
VowelU = VowelU + 1;
}
int strL = str.length();
if(x == strL){
cout << "The original string is: " << str << endl;
cout << "Vowel A: "<< VowelA << endl;
cout << "Vowel E: "<< VowelE << endl;
cout << "Vowel I: "<< VowelI << endl;
cout << "Vowel O: "<< VowelO << endl;
cout << "Vowel U: "<< VowelU << endl;
cout << " " << endl;
}
}
char choice;
cout << "Again? " << endl;
cin >> choice;
if(choice == 'n' || choice == 'N'){userLength = false;}
if(choice == 'y' || choice =='Y')
{
restart = 1; userLength = true;
cin.clear();
cin.ignore();
}
//cout << "What string?";
//cin.get(str, sizeof(str),'\n');
}while(userLength == true);
}
/*
Sources:
printf help
http://www.cplusplus.com/reference/cstdio/printf/
This helped me with the idea of what's a vowel and whats not.
http://www.cplusplus.com/forum/general/71805/
understanding gets()
https://www.programiz.com/cpp-programming/library-function/cstdio/gets
Very important functional part of my program...Logic behind my if statements, fixed my issues with string comparison
What i needed to do was compare each part of one cstring with another c string
strstr compares two strings to see if they are alike to one another this source includes that idea-> https://www.youtube.com/watch?v=hGrKX0edRFg
so I got the idea: What is one c string was all e's, I could then compare each index for similarities with a c string whos definition was all e's.
At this point, why not just go back to standard comparison with strings? But you cant compare const chars to regular chars, so I needed to compare const chars to const chars
hence the idea sparked about the c strings that contained both e and E.
https://stackoverflow.com/questions/18794793/c-comparing-the-index-of-a-string-to-another-string
https://stackoverflow.com/questions/18794793/c-comparing-the-index-of-a-string-to-another-string
Fixed Error with using incremented numbers outside of involved forloop.
https://stackoverflow.com/questions/24117264/error-name-lookup-of-i-changed-for-iso-for-scoping-fpermissive
understanding the use of getline(cin, str_name)
https://stackoverflow.com/questions/5882872/reading-a-full-line-of-input
http://www.cplusplus.com/reference/istream/istream/getline/
http://www.cplusplus.com/forum/beginner/45169/
cin.clear - cin.ignore --fixing issue with cin buffer not accepting new input.
https://stackoverflow.com/questions/46204672/getlinecin-string-not-giving-expected-output
*/
I have been working on this all day but just cant get the output right.
What I want to do is input two numbers, which would be pushed into two arrays so we can subtract or add them and display the result. Seems simple, but there are few catches
Input must be pushed into the array, from the user, one by one.
In case I don't enter a value, code should assume it to be '0' or 'null'. '0' if its in the beginning and 'null' if its in the end. for example if 1st number is 234 and second number is 23 then code should make it into '023' and if I enter first number as 2, 2nd number as 3 but don't enter anything in the end then code should assume it to be null.
Problems
I cant take 'carry' to the next set, in case the sum is greater than 10. Which means the value I m getting is just addition of two numbers doesn't matter if its greater than 10 or not. for example addition of 234 and 890 is giving me [10, 12, 4]
Here is the code.....
#include<iostream>
using namespace std;
main() {
int first[10], second[10], result[10], c, n;
cout << "Enter the number of elements in the array ";
cin >> n;
if (n > 10 || n < 0) {
std::cout << "invalid number, you are a bad reader" << endl;
system("PAUSE");
return 0;
}
cout << "Enter elements of first array " << endl;
for (c = 0; c < n; c++) {
cin >> first[c];
if (first[c] > 9 || first[c] < 0) {
std::cout << "invalid number, you are a bad reader" << endl;
system("PAUSE");
return 0;
}
}
cout << "Enter elements of second array " << endl;
for (c = 0; c < n; c++)
cin >> second[c];
cout << "Sum of elements of two arrays " << endl;
for (c = 0; c < n; c++)
cout << first[c] + second[c] << endl;
if ((first[c] + second[c]) > 9) {
cout << "overflow" << endl;
}
//result[c] = first[c] + second [c];
//cout << result[c] <<endl;
system("PAUSE");
return 0;
}
I would really appreciate some suggestions.
In case your intention is to have the result of e.g.
234 + 890 = 1124
then your summation loop should be in reverse order.
(Since you are reading number of elements of the array from the prompt, you may use this information to input first/second numbers into each array in the order preferred for the following summation loop.)
For the carry problem, you need to setup a variable and use it in the loop like this, for example.
int sum[10] = {0};
int c;
int carry = 0;
for (c = 0; c < n; c++)
{
sum[c] = first[c] + second[c] + carry;
carry = sum[c] / 10;
}
if (c < n)
sum[c] = carry;
else
cout << "overflow";
Use std::vector and learn how to use reverse iterators. So if someone enters 234 you push_back(2), push_back(3), push_back(4) and have [0]=2,[1]=3,[2]=4. Then if the next number is 23 you have [0]=2,[1]=3. Now walk both vector with reverse iterators so the first call to rbegin() will give a pointer to [2]=4 and the other vector will give [1]=3. Now add and carry using push_back into a third vector to store the result. Output the result using reverse iterators to print the result.
This looks like homework, so no sample code.