I am trying to determine if a string is a palindrome by reversing the string and then comparing the letters of both strings. The code is provided underneath. So far whatever I put I always get "is a palindrome " as an output. I am aware of the short cut method for doing this easily and efficiently but trying to understand the long way as well. I am using C++ 11
#include <iostream>
#include <string>
using namespace std;
string reversed = " ";
void reverse_sentence(string s)
{
for (int i = 0; i <= s.length(); i++)
{
reversed = s[i] + reversed;
}
cout << reversed;
}
void is_pal(string reversed, string s)
{
int flag = 0;
// if(s == string(s.rbegin(), s.rend())){
// cout << "is a palindrome"<<endl;
// }else{
// cout <<"failed"<<endl;
// }
for (int i = 0; i <= s.length(); i++)
{
for (int j = 0; j <= reversed.length(); j++)
{
if (s[i] != reversed[j - 1])
{
flag = 1;
}
}
}
if (flag == 1)
{
cout << "is palindrome" << endl;
}
else
{
cout << "not palindrome" << endl;
}
}
int main()
{
string s = "hello";
reverse_sentence(s);
is_pal(s, reversed);
return 0;
}
First issue...
your for loops go out of bounds... length() gives you number of characters in the string. Those characters have index 0 through length() - 1. Because you are using <= s.length() however, then the last time through you get erroneous data, if it doesn't give you out of bounds error. For loops using length() should be from i = 0 to i < s.length()
Biggest issue...
void is_pal(string reversed, string s)
{
int flag = 0;
for (int i = 0; i <= s.length(); i++)
{
for (int j = 0; j <= reversed.length(); j++)
{
if (s[i] != reversed[j - 1])
{
flag = 1;
}
}
}
if (flag == 1)
{
cout << "is palindrome" << endl;
}
else
{
cout << "not palindrome" << endl;
}
}
Your j loop is inside of your i loop.. which means that s[i] never changes as you compare it to every single value in reversed... unless every single character in reversed is the same character... then one of them is guaranteed to be not equal to s[i] which means that flag will be set to 1... which means your function reports it to be a palindrome...
Not only that.. but you already went through the process of doing the reverse... why are you trying to compare against reverse.. in reverse order? That would be the same as comparing against the original string in normal order...
Assuming your reverse_sentence function works correctly... then s.length() is the same as reversed.length(). So to see if s is the same forwards as it is backwards then the letter at each index of s should be exactly the same as the letter at the same index in reversed. Also what you are looking for is when they don't match... so you should initialize your flag to assume at the beginning that they are going to be matching and only set it to false when you discover that they don't match...
void is_pal(string reversed, string s)
{
bool flag = true;
// run loop through length of s or until we know s doesn't match reversed
for (int i = 0; i < s.length() && flag; i++)
{
if (s[i] != reversed[i])
{
flag = false;
}
}
if (flag)
{
cout << "is palindrome" << endl;
}
else
{
cout << "not palindrome" << endl;
}
}
Related
I have a function that receives a character "x" from a user. If the "x" exists in a hard-coded array, "x" is pushed into another array filled with lowdashes in the same position as in the first array. Fo example:
firstArray = ["h", "e", "l", "l","o"]
//user provided character that exist in first array. "e"
lowDashesArray= ["_", "e", "l", "l", "o"]
Then, I want to check if both arrays are equal, my problem is that when the user guesses the firts element in the array (in the above example "h"), the for loop stops iteraring without checking if the other elements are equal. As a result, the block of code that expects both arrays to be equal is executed.
The function looks like so:
bool checkIfLetterExistOnWord(string word, char letter, char* lettersArray, char* lowDashesArray, bool hasWon, bool hasLost, int lives){
bool isCorrectLetter = false;
for(int i = 0; i<word.length(); i++ ){
if(letter == lettersArray[i]){
int position = i;
lowDashesArray[position] = letter;
cout << lowDashesArray;
cout << endl;
isCorrectLetter = true;
}
}
if(isCorrectLetter){
for(int j = 0; j < word.length(); j++){
if(lettersArray[j] == lowDashesArray[j]){
hasWon = true;
//here is the problem. But only when user guesses the first element of the array
}
else{
break;
}
}
if(hasWon){
cout << "You have won";
cout << endl;
cout << hasWon;
cout << endl;
cout << lowDashesArray;
cout << endl;
cout << word;
cout << endl;
return hasWon;
}
else{
cout << "good job. Guess the next letter";
cout << endl;
return hasWon;
}
}
else{
cout << "wrong";
cout << endl;
lives--;
if(lives == 0){
hasLost = true;
cout << "You lost";
return hasLost;
}
else {
cout << "You still have this lives :";
cout << endl;
cout << lives;
cout << endl;
return hasLost;
}
}
}
Both your loop logic is incorrect.
bool isCorrectLetter = false;
for(int i = 0; i<word.length(); i++ ){
if(letter == lettersArray[i]){
int position = i;
lowDashesArray[position] = letter;
cout << lowDashesArray;
cout << endl;
isCorrectLetter = true;
}
}
Here you print the array once for every occurance of the guess character. FUrthermore you do not check, if the letter "was already uncovered". You need to do the printing after the loop and depending on whether you want guessing uncovered chars to be an error, you may need to ajust the check.
for(int j = 0; j < word.length(); j++){
if(lettersArray[j] == lowDashesArray[j]){
hasWon = true;
//here is the problem. But only when user guesses the first element of the array
}
else{
break;
}
}
You're trying to check here, if every char meets a certain criterion (being a non placeholder char). In this case you cannot break early. In general the loop for this kind of check needs to look like this:
bool checkSuccess = true;
for (size_t i = 0; checkSuccess && i != length; ++i)
{
if (!Check(elements[i]))
{
checkSuccess = false;
}
}
Or in your case (using break instead):
hasWon = true;
for(int j = 0; j < word.length(); j++)
{
if(lettersArray[j] != lowDashesArray[j])
{
hasWon = false;
break;
}
}
Imho it's preferrable to separate the replacement logic from io logic. You could e.g. rewrite the logic similar to this:
constexpr char MaskChar = '_';
/**
* Replaces placeholders in \p maskedText, if they the corresponding char in \p clearText
* matches \p guess.
*
* \param[in,out] maskedText the text with some chars replaced with '_'
*
* \return true, if at least one char was replaced, false otherwise
*/
bool GuessChar(std::string const& clearText, std::string& maskedText, char const guess)
{
assert(clearText.length() == maskedText.length());
bool guessCorrect = false;
for (size_t i = 0; i != clearText.length(); ++i)
{
if (maskedText[i] == MaskChar && clearText[i] == guess)
{
guessCorrect = true;
maskedText[i] = guess;
}
}
return guessCorrect;
}
int main()
{
std::string const clearText = "hello";
std::string maskedText(clearText.length(), MaskChar);
size_t lives = 3;
while (lives > 0 && maskedText.find(MaskChar) != std::string::npos)
{
std::cout << "Word: " << maskedText
<< "\nMake your guess!\n";
char c;
std::cin >> c;
if (GuessChar(clearText, maskedText, c))
{
std::cout << "Guess correct!\n";
}
else
{
--lives;
std::cout << "Guess incorrect\n"
<< lives << " lives left\n";
}
}
if (lives > 0)
{
std::cout << "You win!\n";
}
else
{
std::cout << "You loose!\n";
}
}
This question already has answers here:
Convert single char to int
(3 answers)
Closed 2 years ago.
Struggling to separate a string into a stack containing 1's and 0's. Currently I am trying to iterate through the string and parse them into integers to add to a stack.
I am entering 1010, in which the result is 1010 , 010, 10, 0 instead of the desired stack being 1, 0, 1, 0
I have used atoi and stoi along with indexing and the .at method to where I still have the same issue.
#include <iostream>
#include <string>
#include <stack>
using namespace std;
bool isParsableInt(string input) {
string nums = "1234567890";
string test = input;
int attempt;
try {
if (test == "") { return false; }
if (test[0] == '-') {
test = test.substr(1, test.length() - 1);
}
for (int i = 0; i < test.length(); i++) {
if (nums.find(test[i]) == string::npos) { return false; }
attempt = atoi(&test[i]); // String to integer
}
return true;
}
catch (...) { // Catches any error thrown
return false;
}
}
stack<int> createBinaryStack() {
string input;
stack<int> result = stack<int>();
while (true){
cout << "Enter a binary number : ";
cin >> input;
if (!isParsableInt(input)) {
cout << "Invalid Input found - Must be 1's & 0's" << endl;
continue;
}
if (count(input, '0') + count(input, '1') != input.length()) {
cout << "Invalid Number found - Must be 1's & 0's" << endl;
continue;
}
for (int i = 0; i < input.length(); i++) {
cout << stoi(&input.at(i)) << "\t"; // Issue on atoi and stoi functions do not seem to work
result.push(stoi(&input.at(i)));
}
cout << endl;
return result;
}
}
int binaryStackToDecimal(stack<int> stk){
int count = stk.size();
int total = 0;
for (int i = 0; i < count; i++) {
if (stk.top() != 1 && stk.top() != 0) {
return -1;
}
total += stk.top() * pow(2, i);
stk.pop();
}
return total;
}
int main(){
stack<int> stk = createBinaryStack();
while (!stk.empty()) {
cout << stk.top();
stk.pop();
}
cout << endl;
cout << binaryStackToDecimal(stk);
}
stoi(&input.at(i))
should be
input.at(i) - '0'
or, since you are only dealing with zero and one the even simpler
input.at(i) == '1'
also works (as do many other variations).
Your mistake was taking functions that are intended to convert a sequence of digits to a number (stoi and atoi) when all you wanted to do is convert a single digit.
I'm a student currently studying C++ and I have a problem with a code that I am trying to create. The code I am supposed to create is meant to find the hamming distance of 2 words that the user will input. (For e.g "Ironman" and "Iron" hamming distance is "3")
However, I ran into an error when I tried compiling and I can't seem to find out what the problem is. The error of "String subscript out of range" keeps popping up if the first input is longer than the second input.(It only fails to work when I try to input "Spiderman Ironman". Shorter words such as "Sean Sea" works fine.) If the second input is longer than the first input, OR if both the inputs are the same length, the entire code works fine.
string str1;
string str2;
cout << "Question 1" << endl;
cout << "Input two words (separated by space or enter) : ";
cin >> str1;
cin >> str2;
int count = hamming_distance(str1, str2);
cout << "> Hamming distance between \"" << str1 << "\" and \"" << str2 << "\" is " << count << endl;
int i;
int firstLength = str1.length();
int secondLength = str1.length();
int thirdLength;
int counter = 0;
//if the longest word is first string (Where the issue is causing)
if (firstLength > secondLength)
{
thirdLength = firstLength - secondLength;
for (i = 0; i < firstLength; i++)
{
if (str1[i] != str2[i])
{
counter++;
}
}
for (i = 0; i < thirdLength; i++)
{
counter++;
}
}
//if the longest word is second string
else if (secondLength > firstLength)
{
thirdLength = secondLength - firstLength;
for (i = 0; i < secondLength; i++)
{
if (str1[i] != str2[i])
{
counter++;
}
}
for (i = 0; i < thirdLength; i++)
{
counter++;
}
}
//if both words have the same length
else if (firstLength == secondLength)
{
for (i = 0; i < firstLength; i++)
{
if (str1[i] != str2[i])
{
counter++;
}
}
}
return counter;
It would be greatly appreciated if y'all could help me find out what the actual problem is with my code. Thank you!
You need to initialise your variables correctly:
int firstLength = str1.length();
int secondLength = str2.length();
You're also determining that one string is bigger than another, then proceeding to access elements in the shorter string according to the length of the longer one, which is giving you the subscript out of range error. You need to revise the tests when firstLength > secondLength and vice versa.
#include <iostream>
using namespace std;
int main () {
char arr[7];
char x;
for (int i = 0; i < 7; i++)
{
cin >> arr[i];
}
cin >> x;
for (int i = 0; i < 7; i++)
{
if (x == arr[i])
cout << i << endl;
else {
cout <<"Not found";
break;
}
}
}
This program supposed to receive 7 characters and store them in an array then the user have to search for a character, then the program will print the index of that character otherwise, It will print not found, This problem here is when I enter a b c d e f g then search i.e: a It will print 0 not found What is happening here? My debugger is bugged. so I can't use it. I hope you understand my question. How to make it print only index of a character that the user searched for, if not found the program will print not found.
In your code quoted below, if x != arr[0], the if condition will be false in the first turn of for loop, thus directly go to else part, which means printing "Not found" and break.
for (int i = 0; i < 7; i++)
{
if (x == arr[i])
cout << i << endl;
else {
cout <<"Not found";
break;
}
}
Correct way:
bool found = false;
for (int i = 0; i < 7; i++)
{
if (x == arr[i]) {
cout << i << endl;
found = true;
}
}
if ( !found ) {
cout <<"Not found";
}
will you please tell me what will be the procedure to find alphabet occur in all strings(char string lists) in c++
the output will only return matched values(alphabet numbers)
i m trying this
#include <vector>
#include <iostream>
#include <cstdio>
int main()
{
//setup
std::vector<int> alphabetCount;
for (int i = 0; i < 26; ++i)
{
alphabetCount.push_back(0);
}
//now the interactive bit
std::cout << "Enter a line of text\n";
std::string line;
std::getline(std::cin, line);
for (size_t i = 0; i < line.size(); ++i)
{
char currentChar = tolower(line[i]);
if (isalpha(currentChar))
{
++alphabetCount[currentChar - 'a']; //subtract a, so if currentChar = a, 'a' - 'a' = 0, so its index 0
}
}
for (size_t i = 0; i < alphabetCount.size(); ++i)
{
std::cout << "there were " << alphabetCount[i] << " occurences of " << static_cast<char>(i + 'a') << "\n"; //add 'a' for the same reason as above, though we have to cast it to a char.
}
system("pause");
return 0;
}
but it only returns values from single string i want result from all string
The reason why it is taking one string at a time is because you are taking one as input, you should make a vector of string and take input in it.
You have not read the string more than once in program. below is sample program, which is very naive to demonstrate the process. The loop terminating condition can be much better than mine though.
int main()
{
//setup
std::vector<int> alphabetCount;
for (int i = 0; i < 26; ++i)
{
alphabetCount.push_back(0);
}
//now the interactive bit
std::cout << "Enter a line of text\n";
std::string line;
do{
std::getline(std::cin, line);
for (size_t i = 0; i < line.size(); ++i)
{
char currentChar = tolower(line[i]);
if (isalpha(currentChar))
{
++alphabetCount[currentChar - 'a']; //subtract a, so if currentChar = a, 'a' - 'a' = 0, so its index 0
}
}
}while(line != "exit");
--alphabetCount['e' - 'a'];
--alphabetCount['x' - 'a'];
--alphabetCount['i' - 'a'];
--alphabetCount['t' - 'a'];
for (size_t i = 0; i < alphabetCount.size(); ++i)
{
std::cout << "there were " << alphabetCount[i] << " occurences of " << static_cast<char>(i + 'a') << "\n"; //add 'a' for the same reason as above, though we have to cast it to a char.
}
system("pause");
return 0;
}