c++ string loops checking the same words - c++

I have to get let's say 10 words from the user.The program will warn the user if the same word is entered again.What could be the general logic of the program ? I managed to take 10 words from the user with a loop but cant check if the entered words are all different or not ?

Save the words and check if you already have them:
#include <iostream>
#include <set>
#include <string>
int main()
{
std::set<std::string> words;
for (std::string word; std::cin >> word; )
{
if (!words.insert(std::move(word)).second)
{
std::cout << "Word already encountered!\n";
}
}
std::cout << "We got " << words.size() << " distinct words.\n";
// use "words"
}
(You can add a counter or check words.size() if you want at most a certain number of words.)

You could use a std::set, which by definition may not have any duplicates, all elements must be unique. You could do something like
std::set<std::string> uniqueWords;
while (uniqueWords.size() < 10)
{
std::string user;
std::cin >> user;
uniqueWords.insert(user);
}
If the user inputs a duplicate word, set::insert will not add the duplicate, so the length of the set will not increase. The while loop will only terminate once the length of the set grows to 10 elements. Then you can continue on.

Related

How can I use parallel arrays to make a list with quantities and words using c++

I'm stuck on trying to add quantities to this list when it returns the output. It is essentially a list entered by the user that starts with a quantity and is followed by a word. It is then supposed to output the same list but in alphabetical order. I currently have it alphabetized but the numbers that the user enters on the same line, are returned on a separate line from the word when returned in alphabetical order. I know I am prompted to use parallel arrays but have no clue how to incorporate them into this. Nobody has been able to reply to me but I know it is do-able. Thank you all in advance!!
#include <iostream>
#include <string>
#include <iomanip>
#include "functions.h"
#include <algorithm>
#include <set>
using namespace std;
void print(const string& item)
{
cout << item << endl;
}
int main(void)
{
const int MAX_LENGTH = 256;
string items [MAX_LENGTH];
int quantities [ MAX_LENGTH];
string itemChoice;
string qtyChoice;
int numItems= 0;
int randomArray[MAX_SIZE];
{
set<string> sortedItems;
cout << " (type \"exit\" twice to exit, now press enter twice to begin listing your shopping list.): ";
getline (cin, qtyChoice);
getline(cin, itemChoice);
for (int i = 1; ; i++)
{
string itemChoice;
string wholeOrder;
cout << i << ". ";
cin >> itemChoice;
cin >> qtyChoice; // this is how I got it to intake #'s
//getline (cin, qtyChoice);// putting these here actually allow both items to be on one line!! but it leaves awkward spaces.
//getline(cin, itemChoice);
//getline (cin, qtyChoice);
if (itemChoice == "exit")
{
break;
}
sortedItems.insert(qtyChoice);
sortedItems.insert (itemChoice);
//sortedItems.insert(itemChoice);
}
for_each(sortedItems.begin(), sortedItems.end(), &print);
return 0;
}
this is my code and this is what happens as output
(type "exit"to exit, now press enter twice to begin listing your list.):
1. 3828 eijsd
2. 38238 shd
3. 382 hsdid
4. exit
382
38238
3828
eijsd
hsdid
shd
You make no distinction between quantities and words in your set, so they are treated as the same kind of thing, with no connections between them. To preserve the connection, you need a more complicated data structure.
Using parallel arrays is one possibility, but the overhead is a pain. A simpler approach than a pair of arrays would be an array of pairs -- better yet a set of pairs, as you already know that sets provide easy sorting. (A map would also work.)
set< pair<string,string> > sortedItems;
Storing both the word and the quantity in the pair retains the relationship between them. I'll leave it to you to fill in the rest of the details.

How to use single letters to form words

Hey I currently have this code. It gets the user to input strings into an array, with a limit of 5. I plan to use the array to then form words from the array. How can I achieve this?
const int row = 5;
char array[row];
char count = 0;
char letter;
while (count < 5)
{
cout << "Enter a letter: ";
cin >> letter;
array[count] = letter;
count++;
}
cout << "Letter inputed" << endl;
for (count = 0; count < 5; count++)
{
cout << array[count] << " " << endl;
}
system("pause");
Here's a hint to get you started on the right track: don't even consider using std::next_permutation unless this is something you'll only ever use once or twice (and probably not even then, because it's actually more complicated than doing the job right).
Using std::next_permutation, your function will be approximately N! times slower than necessary1 -- in the case of 5 letters, that'll be 120 times slower, and if you ever use longer words, it'll get worse very quickly (e.g., for 10 letters it's over 3.5 million).
Instead, start by pre-processing your dictionary. Instead of a std::set<std::string> of words, create an std::map<std::string, std::vector<string>> (or std::unordered_map, though English has few enough words that this probably won't make a huge difference). As you read in a word from the dictionary, create a sorted version of that string. Use that as the key, and push the original version of the word onto the vector for that key.
Then when you get a word from the user, sort it, look that up in the map, and the associated vector will contain every word (from your dictionary) that can be created from those letters.
1. If you use std::map instead of std::unordered_map, that should be something like N!/(log N), but N! grows so fast and log N grows so slowly that it the difference is negligible (if you get N large enough that log N = 3, N! will be so large that N!/log N computation steps...well, you start to get into questions of cosmology, like whether the universe will have died of heat death before then (to which the answer seems to be "yes, probably").
Here's a hint to get you started. There's a function in the standard library called std::next_permutation. Assuming you have a dictionary of words to check against, a possible solution could look like this:
std::sort(array, array + row);
do {
// Check if array is a word.
} while (std::next_permutation(array, array + row));
This will cycle through every permutation of letters. It's now up to you to verify that it is a valid word.
This solution uses an associative array to map from sorted letters of the word to the words having such sorted letters. It's thus possible to get an answer with one lookup in the map, which takes asymptotically O(log N) time, where N is a size of your dictionary.
Create a file named dic.txt. In case you're using Visual Studio it should be in the same directory as your *.cpp files. Put several words inside in a "word in a row" format. Try the following code:
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
int main() {
// Dictionary file is in a "word in a row" format
map< string, vector<string> > dictionary;
ifstream dictionary_file("dic.txt");
if (!dictionary_file.good()) {
cout << "File doesn't exist" << endl;
return 0;
}
string word;
while (dictionary_file >> word) {
string key = word;
sort(key.begin(), key.end());
dictionary[key].push_back(word);
}
// Read the letters
string letters;
cin >> letters;
if (letters.size() > 5) {
cout << "Too much letters" << endl;
return 0;
}
// Sort the letters
sort(letters.begin(), letters.end());
// Output the answers
vector<string> & ret = dictionary[letters];
for (size_t i = 0, ilen = ret.size(); i < ilen; ++i) {
cout << ret[i] << endl;
}
}
Mention that such a solution cares for a case your letters are in. In case you don't need it, you can add calls to strtolower function (got that name from PHP) before you add a word to your dictionary and before you sort your letters.
string strtolowers(string const & word) {
string ret = word;
transform(ret.begin(), ret.end(), ret.begin(), tolower);
return ret;
}
You'll need to add <cctype> header for this function to work.

C++ stringstream, if word is numeric, divide by two

I am fairly new to programming and have to create a program which reads the prompt: "I have 8 dollars to spend." It then needs to print out with each word on a separate line, and then if any of the strings is numeric, it needs to be divided by 2. Therefore it should end up printing out as:
I
have
4
dollars
to
spend.
I have managed to do everything, except finding the numeric value and dividing it by 2. So far I have this:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
string prompt;
string word;
cout << "Prompt: ";
getline(cin, prompt);
stringstream ss;
ss.str(prompt);
while (ss >> word)
{
cout << word << endl;
}
return 0;
}
After looking through various other posts, I cannot manage to get this to work. I'm assuming its an if/else statement within the while loop along the lines of, if numeric, set int num to num / 2 then cout << num << endl;, else cout << word << endl;, but I can't figure it out.
Thanks in advance.
You can use the stringstream class, which handles conversions between strings and other data types, to attempt to convert a given string to a number. If the attempt is successful, you know
The stringstream object allows you to treat a string as though it is a stream similar to cin or cout.
Incorporate this into your while loop, like so:
while (ss >> word)
{
int value = 0;
stringstream convert(word); //create a _stringstream_ from a string
//if *word* (and therefore *convert*) contains a numeric value,
//it can be read into an _int_
if(convert >> value) { //this will be false if the data in *convert* is not numeric
cout << value / 2 << endl;
}
else
cout << word << endl;
}
The strtol (C++11 version that works on std::string directly: std::stol) function is really good for testing whether a string holds a number, and if so, what the numeric value is.
Or you could continue using iostreams like you have been... try extracting a number (int or double variable), and if that fails, clear the error bit and read a string.
I dont have 50 rep so I cant comment, thats why I'm writing it as answer.
I think you can check it character by character, using Ascii value of each char, & if there are ascii values representing numbers between two spaces(two \n in this case as you've already seperated each word), then you have to divide the number by 2.

Read input numbers separated by spaces

This may be a total beginner's question, but I have yet to find an answer that works for me.
Currently, I'm writing a program for a class that takes in a user's input (which can be one or more numbers separated by spaces), then determines whether the number is prime, perfect, or neither. If the number is perfect, then it will display the divisors.
Thus far, I've already written the code for the prime, perfect, and listing the divisors. I'm stuck on the input portion of my program. I don't know how to get the input that's separated by spaces to go through my loops one at a time.
This is my current program:
cout<<"Enter a number, or numbers separated by a space, between 1 and 1000."<<endl;
cin>>num;
while (divisor<=num)
if(num%divisor==0)
{
cout<<divisor<<endl;
total=total+divisor;
divisor++;
}
else divisor++;
if(total==num*2)
cout<<"The number you entered is perfect!"<<endl;
else cout<<"The number you entered is not perfect!"<<endl;
if(num==2||num==3||num==5||num==7)
cout<<"The number you entered is prime!"<<endl;
else if(num%2==0||num%3==0||num%5==0||num%7==0)
cout<<"The number you entered is not prime!"<<endl;
else cout<<"The number you entered is prime!"<<endl;
return 0;
It works, but only for a single number. If anyone could help me to get it to be able to read multiple inputs separated by spaces, it'd be greatly appreciated. Also, just a side note, I do not know how many numbers will be entered, so I can't just make a variable for each one. It will be a random amount of numbers.
Thanks!
By default, cin reads from the input discarding any spaces. So, all you have to do is to use a do while loop to read the input more than one time:
do {
cout<<"Enter a number, or numbers separated by a space, between 1 and 1000."<<endl;
cin >> num;
// reset your variables
// your function stuff (calculations)
}
while (true); // or some condition
I would recommend reading in the line into a string, then splitting it based on the spaces. For this, you can use the getline(...) function. The trick is having a dynamic sized data structure to hold the strings once it's split. Probably the easiest to use would be a vector.
#include <string>
#include <vector>
...
string rawInput;
vector<String> numbers;
while( getline( cin, rawInput, ' ' ) )
{
numbers.push_back(rawInput);
}
So say the input looks like this:
Enter a number, or numbers separated by a space, between 1 and 1000.
10 5 20 1 200 7
You will now have a vector, numbers, that contains the elements: {"10","5","20","1","200","7"}.
Note that these are still strings, so not useful in arithmetic. To convert them to integers, we use a combination of the STL function, atoi(...), and because atoi requires a c-string instead of a c++ style string, we use the string class' c_str() member function.
while(!numbers.empty())
{
string temp = numbers.pop_back();//removes the last element from the string
num = atoi( temp.c_str() ); //re-used your 'num' variable from your code
...//do stuff
}
Now there's some problems with this code. Yes, it runs, but it is kind of clunky, and it puts the numbers out in reverse order. Lets re-write it so that it is a little more compact:
#include <string>
...
string rawInput;
cout << "Enter a number, or numbers separated by a space, between 1 and 1000." << endl;
while( getline( cin, rawInput, ' ') )
{
num = atoi( rawInput.c_str() );
...//do your stuff
}
There's still lots of room for improvement with error handling (right now if you enter a non-number the program will crash), and there's infinitely more ways to actually handle the input to get it in a usable number form (the joys of programming!), but that should give you a comprehensive start. :)
Note: I had the reference pages as links, but I cannot post more than two since I have less than 15 posts :/
Edit:
I was a little bit wrong about the atoi behavior; I confused it with Java's string->Integer conversions which throw a Not-A-Number exception when given a string that isn't a number, and then crashes the program if the exception isn't handled. atoi(), on the other hand, returns 0, which is not as helpful because what if 0 is the number they entered? Let's make use of the isdigit(...) function. An important thing to note here is that c++ style strings can be accessed like an array, meaning rawInput[0] is the first character in the string all the way up to rawInput[length - 1].
#include <string>
#include <ctype.h>
...
string rawInput;
cout << "Enter a number, or numbers separated by a space, between 1 and 1000." << endl;
while( getline( cin, rawInput, ' ') )
{
bool isNum = true;
for(int i = 0; i < rawInput.length() && isNum; ++i)
{
isNum = isdigit( rawInput[i]);
}
if(isNum)
{
num = atoi( rawInput.c_str() );
...//do your stuff
}
else
cout << rawInput << " is not a number!" << endl;
}
The boolean (true/false or 1/0 respectively) is used as a flag for the for-loop, which steps through each character in the string and checks to see if it is a 0-9 digit. If any character in the string is not a digit, the loop will break during it's next execution when it gets to the condition "&& isNum" (assuming you've covered loops already). Then after the loop, isNum is used to determine whether to do your stuff, or to print the error message.
You'll want to:
Read in an entire line from the console
Tokenize the line, splitting along spaces.
Place those split pieces into an array or list
Step through that array/list, performing your prime/perfect/etc tests.
What has your class covered along these lines so far?
int main() {
int sum = 0;
cout << "enter number" << endl;
int i = 0;
while (true) {
cin >> i;
sum += i;
//cout << i << endl;
if (cin.peek() == '\n') {
break;
}
}
cout << "result: " << sum << endl;
return 0;
}
I think this code works, you may enter any int numbers and spaces, it will calculate the sum of input ints
std::vector<int> num{};
int buf;
do{
std::cin >> buf;
num.push_back(buf);
}while(std::cin.peek() == ' ');
In C language you can to it using scanf like this:
scanf('%d %d',&a,&b);

input operation

Consider this problem
User will enter input to one dimensional array(char test[100]) in sequence of
letter/space/index/space/letter....
like this
a 1 s 1 e 3 r 4 r 3 t 3 until an 'enter'is hit.
Index can be repeated as well as letter.
So above sequence should mean test[1]=a ,test[1]=s and so on.
To build this problem what I have thought is that I should test whether character entered is newline(enter) or not.
but i don't understand how to do that
can you suggest some code for this
Scrap the entire idea; your question is wrong. The user does not enter a char[100]. Rather, the user enters a string. And suddenly it's very easy:
#include <string>
#include <iostream>
int main()
{
std::string user_input;
std::getline(std::cin, user_input);
// done: now use user_input
}
Now you can iterate over the string, tokenize it, or whatever. For example:
std::istringstream iss(user_input);
char c;
int n;
while (iss >> c >> n)
{
std::cout << "We have a pair (" << c << ", " << n << ")\n";
}