I have a completed code for my class; it creates a randomized string based on how many characters that the user asks for, and it then allows for the user to specify if they want to find a particular pair of characters in the string. That last part is based on a if/else statement that either gives the location, or is suppose to tell them there is no pair in the string.
My issue is that, when given a pair to find, if its in the string it gives the corrected statement, however, it also gives the else statement, repeated several times. if the pair is not in the string, it then gives the correct else statement, but repeats the cout several times. I don't know how to solve this issue.
Here is my code and screen shots of my outputs.
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main() {
int i=0, n;
char alphabet[26];
char RandomStringArray [100];
char Ltr1, Ltr2;
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";
cout<<"What letter pair would you like to find? ";
cin>>Ltr1>>Ltr2;
for (i=0; i<n; i++)
if (Ltr1==RandomStringArray[i] && Ltr2== RandomStringArray[i+1]){
cout<<"The pair is in the string starting at character number "<<i+1<<" in the string. \n";
}
else if (Ltr1!=RandomStringArray[i] && Ltr2!= RandomStringArray[i+1])
cout<<"no";
return 0;
}
Your final for loop is looping through every character in the random string from begin to end, which is fine for searching, but it is outputting the result of comparing every character, which is not what you want. Don't display any output at all until the loop is finished, eg:
for (i = 0; i < (n-1); i++)
{
if (RandomStringArray[i] == Ltr1 && RandomStringArray[i+1] == Ltr2)
break;
}
if (i < (n-1))
cout << "The pair is in the string starting at character number " << i+1 << " in the string.\n";
else
cout << "The pair is not found in the string.\n";
I would suggest wrapping the search in a function, eg:
int findPair(const char *str, int len, char Letter1, char Letter2)
{
for (i = 0; i < (len-1); i++)
{
if (str[i] == Letter1 && str[i+1] == Letter2)
return i;
}
return -1;
}
...
i = findPair(RandomStringArray, n, Ltr1, Ltr2);
if (i != -1)
cout << "The pair is in the string starting at character number " << i+1 << " in the string.\n";
else
cout << "The pair is not found in the string.\n";
That being said, since you are using C++ anyway, you should go full C++, not a mix of C and C++, eg:
#include <iostream>
#include <string>
#include <random>
#include <algorithm>
int main() {
int n;
char alphabet[26];
std::string RandomString;
char LtrPair[2];
std::generate(std:begin(alphabet), std::end(alphabet), [ch = 'a'] () mutable { return ch++; } );
std::cout << "How many letters do you want in your random string: ";
std::cin >> n;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 25);
RandomString.resize(n);
std::generate(RandomString.begin(), RandomString.end(), [&](){ return alphabet[dis(gen)]; };
std::cout << RandomString << "\n";
std::cout << "What letter pair would you like to find? ";
cin >> LtrPair[0] >> LtrPair[1];
auto pos = RandomString.find(LtrPair, 0, 2);
if (pos != std::string::npos)
std::cout << "The pair is in the string starting at character number " << pos+1 << " in the string.\n";
else
std::cout << "The pair is not found in the string.\n";
return 0;
}
Since you have placed your if...else construct inside of a for loop, it is evaluated every time. This means that for every instance where the first condition isn't true, the else clause is executed, causing your "no" message to repeat.
Related
I have a character array that produces a random array of lowercase letters in the length that the user inputs. my problem is that after the array of random letters is produced the user inputs a pair of charaters(two letters) and my code should check if that pair is in the random array that was produced. it worked fine when it just checked for one letter but when i introduced the second one it does not work.I would appreciate any help.
#include <ctime>
#include <iostream>
#include <cstdlib>
int main() {
std::srand(std::time(NULL));
int i, num;
char letter1, letter2, ch, r;
const char chars[]="abcdefghijklmnopqrstuvwxyz";
std::cout << "How many letters do you want in your string? ";
std::cin >> num;
for (i=0; i<num; i++)
{
ch = chars[rand()%26];
std::cout << ch;
}
std::cout << "\nWhat letter pair would you like to find? ";
std::cin >> letter1 >> letter2;
if ((chars[i] == letter1) && (chars[i+1]==letter2))
std::cout << "It is in your string. ";
else
std::cout << "You do not have " << letter1 << letter2 << " in your string";
}
First, you are not storing your randomly generated chars
for (i=0; i<num; i++)
{
ch = chars[rand()%26];
std::cout << ch;
}
This just writes a random char in ch and displays it on the console with each iteration. You don't store your data, ch just contains the last random char after your loop ends and everything else is lost.
The part where you want to search is double wrong.
if ((chars[i] == letter1) && (chars[i+1]==letter2))
std::cout << "It is in your string. ";
else
std::cout << "You do not have " << letter1 << letter2 << " in your string";
This isn't inside a loop, i is simply always going to be num-1.
The array you are checking is chars which is your const array containing "abcdefghijklmnopqrstuvwxyz". This doesn't contain your randomly generated chars.
I have to solve a task so it prints the min, the max and the mode of a set of strings. First I store the strings in a vector, than I sort them and then I print the first and the last of the elements of the vector, which is fine. But I have hard times finding the mode of them. Here is the code I wrote.
#include<stdafx.h>
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
vector<string>words;
cout << "Please enter some words. When finished, just enter 'stop'.\n";
string ant;
int count = 0;
int max = 0;
while (cin >> ant) {
if (ant != "stop") {
words.push_back(ant);
}
else
break;
}
sort(words.begin(), words.end());
cout << "The min of the entered words is " << words[0] << "\n";
cout << "The max of the entered words is " << words.back() << "\n";
}
So far this is good. It does the job as I want. But the problem comes when I have to find the mode of the strings. I found some code on the net for finding mode of given integers and it works for integers. I tried to modify it for strings but I could not get it to work. Here is the code:
for (string test = 0; test<words.size(); ++test) {
if (words[test] == words[test + 1]) {
count++;
}
else if (words[test] != words[test + 1]) {
if (count>max) {
max = count;
mode = words[test];
}
count = 0;
}
}
This gives me a lot of errors, I do not know where to begin. I think the problem is that this is not a proper way to make iteration of strings. I found some explanations about iteration of strings, but its so confusing for me. Any help will be appreciated.
Your modified version of the algorithm that finds the mode of the entered words is correct. The only thing i can say about it is, count and max are keywords in C++ so you'd have to change the names to avoid undesired effects. Also, don't forget to declare mode as type string.
With little modification of your code, this works;
#include<iostream>
#include<vector>
#include <map>
#include<string>
#include<algorithm>
using namespace std;
int main() {
vector<string>words;
cout << "Please enter some words. When finished, just enter 'stop'.\n";
string ant;
int count = 0;
int max = 0;
while (cin >> ant) {
if (ant != "stop") {
words.push_back(ant);
}
else
break;
}
sort(words.begin(), words.end());
cout << "The min of the entered words is " << words[0] << "\n";
cout << "The max of the entered words is " << words.back() << "\n";
//Finding the mode of the entered words
int _count = 0;
int _max = 0;
string mode;
for (unsigned int test = 0, j = 1; test<words.size(); test++, j++) {
if (words[test] == words[j]) {
_count++;
}
else if (words[test] != words[j]) {
if (_count>_max) {
_max = _count;
mode = words[test];
}
_count = 0;
}
}
cout << "The mode of the entered words is " << mode;
}
So I'm working on this homework assignment and I'm really having trouble. I'm supposed to count the number of words more than two characters(have to contain one letter), unique words, and the number of times each unique word appears in the Programming Execution Environment. I'm also supposed to get input to search for in the PEE and output the number of times it appears and the line where it appears. I have some of it working, but I'm really struggling with counting how many times each word appears. I know my code is really bad right now, but that's why I'm here. I'm really struggling with these string functions for some reason. Any help is really appreciated!
#include <iostream>
#include <cstring>
#include <string>
#include <cctype>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
//PEE string
string envstr("");
bool checkChar(unsigned c)
{
return (ispunct(c) || isspace(c) || isblank(c) || isdigit(c) || c == '\n');
}
void searchWord(unsigned c, size_t length)
{
multiset<string> words;
vector<string> vwrds; //this was something i was trying out
string tempword;
while (!checkChar(envstr[c]) && c < length)
{
tempword = tempword + envstr[c]; //problem here
c++;
}
tempword = tempword + " ";
vwrds.push_back(tempword);
words.insert(tempword); //this is just a bunch of random letters
tempword.clear();
//for (multiset<string>::const_iterator i(words.begin()), end(words.end()); i != end; i++)
//cout << *i;
}
bool checkIfWord(char c)
{
bool valid = false;
int i;
for (i = c; i > c - 2; i--)
{
if (!checkChar(envstr[i]))
valid = true;
}
if (valid)
searchWord(i, envstr.length());
return valid;
}
int main()
{
//this code given by my instructor
extern char **environ; // needed to access your execution environment
int k = 0;
size_t wordCount = 0;
while (environ[k] != NULL)
{
cout << environ[k] << endl;
string str(environ[k]);
envstr = envstr + str;
k++;
}
//iterator to count words
wordCount = count_if(envstr.begin(), envstr.end(), checkIfWord);
cout << "\nThe PEE contains " << wordCount << " words. \n";
//transform environment string to lowercase
transform(envstr.begin(), envstr.end(), envstr.begin(), tolower);
string input;
do
{
cout << "Enter your search item: \n";
cin >> input;
//string can only be forty characters
if (input.length() > 40 || input == "\n")
{
cout << "That search query is too long. \n";
continue;
}
//change the search string to lowercase, like the envstr
transform(input.begin(), input.end(), input.begin(), tolower);
int j = 0;
int searchCount = 0;
vector<size_t> positions;
size_t pos = envstr.find(input, 0);
//search for that string
while (pos != string::npos)
{
positions.push_back(pos);
pos = envstr.find(input, pos + 1);
searchCount++;
}
cout << "\nThat phrase occurs a total of " << searchCount << " times.\n";
cout << "It occurs in the following lines: \n";
//output where that string occurs
for (vector<size_t>::iterator it = positions.begin(); it != positions.end(); ++it)
{
for (int i = *it; i < envstr.length() - 1 && checkChar(envstr[i]); i++)
{
cout << envstr[i];
}
cout << endl;
}
positions.clear();
} while (input != "END");
cin.get();
return 0;
}
First, your function checkChar() returns false when the parameter is a char, so if you want to print where that string occurs, it should be:
for (int i = *it; (i < envstr.length() - 1) && !checkChar(envstr[i]); i++)
{
cout << envstr[i];
}
Second, the code for counting words makes no sense and there is a potential out-of-bounds here: if (!checkChar(envstr[i])), I would suggest you to split the string using delimter '\', then do something.
Using C++, I'm trying to make a hangman game to become better at using C++ and programming in general. Anyways, the issue I'm facing is that I'm not sure how to replace the dashes within a string with the letter the user has guessed.
I think my problem is with the fact the word chosen is randomly chosen from an array and I'm not sure how to go about finding the positions within the randomly chosen string which consists of the guessed character.
I have commented out the area that's causing the issue.
#include <iostream>
#include <array>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <cstddef>
#include <algorithm>
using namespace std;
int main()
{
string words[3] = {"stack", "visual", "windows"};
string guess;
cout << "Welcome to hangman.\n";
cout << "\n";
srand(time(NULL));
int RandIndex = rand() % 3;
string selected = words[RandIndex];
for (int i = 1; i <= selected.size(); i++) {
cout << "_ ";
}
cout << "\n";
cout << "\nType in a letter: ";
cin >> guess;
cout << "\n";
if (selected.find(guess) != string::npos) {
/*for (int i = 1; i <= selected.size(); i++) {
if (selected.find(guess) != string::npos) {
cout << "_ ";
} else {
cout << guess << " ";
}
}*/
} else {
cout << "\nNay!\n";
cout << "\n";
}
cout << "\n";
cout << "\n";
system("PAUSE");
return 0;
}
I was thinking about using the replace() function but the problem I face here is that I'm not replacing the string within selected variable but sort of iterating through the word itself, if that made any sense whatsoever?
Use a second string, that is initialized with the underscores. If the find function doesn't return string::npos it returns the position in the string, and this is the same position you should change in the string with the underscores as well.
You actually need to use a second string to store the "guessed" string; this is because you need to keep track of all the guessed letters and display them.
something like :
string s ="test";
string t=""; //empty string
for(int i=0;i<s.size();i++)
t.append("_"); //initialize the guess string
cout<<t<<'\n';
char c;
cin >> c;
int pos = s.find(c); //get the first occurrence of the entered char
while(pos!=-1) //look for all occurrences and replaced them in the guess string
{
t.replace(pos,1,1,c);
pos = s.find(c, pos+1);
}
I think you need to maintain some extra state while looping - to keep track of which letters have / haven't been guessed.
You could add a new string current_state which is initially set to the same length as the word but all underscores. Then, when the player guesses a letter, you find all instances of that letter in the original word, and replace the underscore with the letter guessed, at all the positions found but in current_state.
First i would initialize a new string to show the hidden word:
string stringToDisplay = string( selected.length(), '_');
Then For each letter given by the user i would loop like this:
(assuming guess is letter)
size_t searchInitPos = 0;
size_t found = selected.find(guess, searchInitPos));
if (found == string::npos)
{
cout << "\nNay!\n";
cout << "\n";
}
while( found != string::npos)
{
stringToDisplay[found] = guess;
searchInitPos = found+1;
found = selected.find(guess, searchInitPos));
}
cout << stringToDisplay;
Hope this will help
I think it should be that:
string words[3] = {"stack", "visual", "windows"};
char guess;
string display;
cout << "Welcome to hangman.\n";
cout << "\n";
srand(time(NULL));
int RandIndex = rand() % 3;
string selected = words[RandIndex];
for (int i = 0; i < selected.size(); i++) {
display.insert(0, "_ ");
}
cout << display;
while(display.find("_ ") != string::npos) {
cout << "\n";
cout << "\nType in a letter: ";
cin >> guess;
cout << "\n";
bool flag = false;
for (int i = 0; i < selected.size(); i++) {
if (selected[i] == guess) {
display.replace(i*2, 1, 1, guess);
flag = true;
}
}
if (!flag) {
cout << "\nNay!\n";
cout << "\n";
} else {
cout << display;
}
}
int main()
{
char sentence;
int count;
cout << "Enter sentence: ";
cin >> sentence;
count = 0;
while ( sentence == 'b' || 'B' ) {
count++;
}
cout << "Number of b's: " << count * 1 << endl;
return 0;
}
The counting must also stop at all punctuation. I can't seem to get it to give me the correct count.
It's your while loop. The variable sentence is not changed inside the loop, so the loop may execute forever.
You may want to use std::string for a sentence and char for a character in the sentence.
Edit 1: Example
char letter;
cout << "Enter a sentence:\n";
while (cin >> letter)
{
// Check for sentence termination characters.
if ((letter == '\n') || (letter == '\r') || (letter == '.'))
{
break; // terminate the input loop.
}
// Put your letter processing code here.
} // End of while loop.
There are a couple suspicious points in your program:
char sentence;
cin >> sentence;
This looks like it would only be reading one character. You might want to getline() and save user input in a std::string
As for
while ( sentence == b || B ) {
This wouldn’t even compile since b and B are undefined. Maybe it should be
if ( cur_byte == ‘b' || cur_byte == ‘B’ )
count++
where cur_byte is some properly maintained iterator inside your string
#include <string>
Use string. string sentence; And create a for long as:
for(int i=0; i<sentence.length(); i++)
if(sentence[i] == b || B) count ++;
So simple ;) Good luck ;)
EDIT 1:
If you will only use while:
int count = sentence.length();
int count2 = 0;
while(count != 0)
{
if(sentence[count] == b||B) count2++
count--;
}
Good luck ;)
#include <iostream>
using namespace std;
int main()
{
char c;
int n = 0;
cout << "Enter sentence: ";
while (cin >> c && !ispunct(c)) if (tolower(c) == 'b') n++;
cout << "Number of b's: " << n << endl;
return 0;
}
Example:
Enter sentence: Two B or not two b, that is the question Bb.
Number of b's: 2