I was trying to do that simple code so i can practice c++, but I end up getting crazy because of my own code, the objective is to see if a string is a palindrome or not. Here it is. The problem I got is when I write "lol", it says: "is not a palindrome".
#include <iostream>
#include <string>
using namespace std;
int main() {
system("Color 0A");
string word;
bool is_string;
int a = 0;
int points;
cout << "write a word and see if it is a palindrome" << endl;
cin >> word;
for (int i = word.length(); i >= 0; i--)
{
if (word[i] != word[a])
{
is_string = false;
cout << "is not a palindrome";
i = 0;
}
if (word[i] == word[a])
{
points++;
}
a++;
}
if (points == word.length())
{
is_string = true;
cout << "is a palindrome";
}
}
Because string indexes start with 0 instead of 1, the last character's index will be 1 less than what you would expect. Replace word.length() with word.length() - 1.
It's a property in all codes, the first letter has the index '0' and the length of anything has the real length of the world, it means that for the word "lol", the "l" would have the index '0', the "o" the index '1' and the "l" the index '2', by trying to compare the letter with the index '3', you are trying to compare the word with and empty letter, so it couldn't works.
So to fix it you have 2 solutions
Replace everywhere the i by i+1 it means replacing word[i] by word[i+1]
Replace for (int i = word.length(); i >= 0; i--) by for (int i = word.length() - 1; i >= 0; i--)
Related
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'm new to C++ and coding. I tried to make a hangman game as a beginner project. The problem I have is that the game only works when the letters of the word is typed in order. If the word is "flow" for instance, I have to type each letter consecutively (f,l,o,w). Any other variations is not accepted and I don't know why. I need help debugging this issue. I'm not sure if .replace is the method I should be using here. I found this method on the internet and I thought it would do what I needed it to do.
#include <iostream>
#include <string>
#include <time.h>
#include <stdlib.h>
using namespace std;
string getString(char guess) {
string s(1, guess);
return s;
}
int main() {
unsigned int seed;
int randomNumber = 0;
char guess;
string underscore;
seed = time(0);
cout << "Hangman game\n";
srand(seed);
randomNumber = (rand() % 5);
string wordList[5] = {"closet", "flow", "sheep", "see", "chocolate"};
string word = wordList[randomNumber];
int wordLength = word.length();
cout << "The word has " << wordLength << " letters\n";
for (int x = 0; x < wordLength; x++) {
underscore += "_ ";
}
cout << underscore << endl;
string holder = underscore;
for (int j = 0; j < wordLength; j++) {
cout << "\n\nType in a letter: ";
cin >> guess;
if (guess == word[j]) {
size_t found = word.find(guess);
holder.replace(found, 2, getString(guess));
cout << "\n";
word.replace(found, 1, "*");
cout << holder;
}
else {
}
}
return 0;
}
Here are some observations that might help you:
Don’t declare all variables at the top of your function. Declare them as you need them.
Avoid hard-coding (wordList[5]). Add as many as strings as you need in your array. Use the following to find out how many are (see sizeof):
string wordList[] = { "closet", "flow", "sheep", "see", "chocolate" };
size_t wordCount = sizeof wordList / sizeof wordList[0];
You do not need to manually fill the underscore string. Use the following constructor:
string underscore(word.length(), '_');
The user might enter uppercase letters. Convert them to lowercase. Otherwise you will not find them:
guess = tolower(guess);
You do not need fancy functions to find out where the entered character is located. Just use a loop:
//...
bool found = true;
for (int i = 0; i < word.length(); i++)
{
if (word[i] == guess) // is the letter at position i the same as the one entered?
underscore[i] = guess; // replace it
if (underscore[i] == '_')
found = false;
}
if (found)
{
cout << "Good job!" << endl;
return 0;
}
//...
I can't for the life of me get my code to work. It identifies palindromes correctly, but for some reason, some non-palindromes words get marked as palindromes. Not all, just sum. And biggest headache of all, I can't figure out the correlation between of the non-palindromes that pass.
Any other feedback is appreciated.
#include <iostream>
#include <ctype.h>
#include <string.h>
#include <limits>
using namespace std;
int main() {
const int a(15);
char Line[a + 1];
int i;
do {
cout << "Enter a possible palindrome" << endl;
cin.getline(Line, a + 1);
if (cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
else;
for (int i = 0; i < strlen(Line); i++) {
Line[i] = (char)tolower(Line[i]);
}
int c = strlen(Line);
for (int i = 0; i < c / 2; i++) {
while (!(((int)Line[c - 1 - i] >= 'a' && (int)Line[c - 1 - i] <= 'z') || ((int)Line[c - 1 - i] >= 'A' && (int)Line[c - 1 - i] <= 'Z'))) {
c--;
}
if ((Line[i] == Line[c - 1 - i]))
{
cout << "is a Palindrome" << endl;
}
else
cout << Line << " is not a palindrome." << endl;
break;
}
} while (strcmp(Line, "END") != 0);
return 0;
The string is a palindrome if the condition Line[i] == Line[c-1-i] holds for all i < c/2. You print out that its a palindrome provided two of the characters match.
Eg: Your program would say:
"abdca" //is a palindrome since the first and last character match.
I think your code is intricacy a bit. Let's assume that the input is always readable, so you just need to cin >> Line;. Let n is length of string. Now we use a loop from 0 to n / 2 to check the symmetry of string. If Line[i] != Line[n - i - 1] that means Line is not symmetry (palindrome) then we just need to print the result and return 0. If the program pass the loop that mean Line is pallindrome. This problem is quite easy. For me, the way you think of it is complex a bit.
This is the question that needs to be implemented:
Write a C++ program that stops reading a line of text when a period is
entered and displays the sentence with correct spacing and capitalization. For this program, correct spacing means only one space between words, and all letters should be lowercase, except the first letter. For example, if the user enters the text "i am going to Go TO THe moVies.", the displayed sentence should be "I am going to go to the movies."
I have written my piece of code which looks like this:
// Processing a sentence and verifying if it is grammatically correct or not (spacing and capitalization)
//#include <stdio.h>
//#include <conio.h>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string sentence;
cout << "Enter the sentence: ";
getline(cin, sentence);
int len = sentence.length();
// Dealing with capitalizations
for (int j = 0; j <= len; j++)
{
if (islower(sentence[0]))
sentence[0] = toupper(sentence[0]);
if(j>0)
if(isupper(sentence[j]))
sentence[j] = tolower(sentence[j]);
}
int space = 0;
do
{
for (int k = 0; k <= len; k++)
{
if(isspace(sentence[k]))
{
cout << k << endl;
int n = k+1;
if(sentence[n] == ' ' && n <=len)
{
space++;
cout << space <<endl;
n++;
cout << n <<endl;
}
if(space!= 0)
sentence.erase(k,space);
cout << sentence <<endl;
}
}
len = sentence.length();
//cout << len <<endl;
} while (space != 0);
}
With this I was able to deal with capitalization issue but problem occurs when I try to check for more than one whitespace between two words. In the do loop I am somehow stuck in an infinite loop.
Like when I try and print the length of the string (len/len1) in the first line inside do-while loop, it keeps on running in an infinite loop. Similarly, when I try and print the value of k after the for loop, it again goes into infinite loop. I think it has to do with my use of do-while loop, but I am not able to get my head around it.
This is the output that I am receiving.
there are a few different issues with this code, but i believe that the code below addresses them. hopefully this code is readable enough that you can learn a few techniques. for example, no need to capitalize the first letter inside the loop, do it once and be done with it.
the usual problem with infinite loops is that the loop termination condition is never met--ensure that it will be met no matter what happens in the loop.
#include <iostream>
#include <string>
using namespace std;
int main() {
string sentence;
cout << "Enter the sentence: ";
getline(cin, sentence);
int len = sentence.find(".", 0) + 1; // up to and including the period
// Dealing with capitalizations
if (islower(sentence[0]))
sentence[0] = toupper(sentence[0]);
for (int j = 1; j < len; j++)
if(isupper(sentence[j]))
sentence[j] = tolower(sentence[j]);
// eliminate duplicate whitespace
for (int i = 0; i < len; i++)
if (isspace(sentence[i]))
// check length first, i + 1 as index could overflow buffer
while (i < len && isspace(sentence[i + 1])) {
sentence.erase(i + 1, 1);
len--; // ensure sentence decreases in length
}
cout << sentence.substr(0, len) << endl;
}
Here goes
std::string sentence;
std::string new_sentence;
std::cout << "Enter the sentence: ";
std::getline(std::cin, sentence);
bool do_write = false; // Looking for first non-space character
bool first_char = true;
// Loop to end of string or .
for (unsiged int i = 0; i < sentence.length() && sentence[i] != '.'; ++i) {
if (sentence[i] != ' ') { // Not space - good - write it
do_write = true;
}
if (do_write) {
new_sentence += (first_char ? toupper(sentence[i]) : tolower(sentence[i]);
first_char = false;
}
if (sentence[i] == ' ') {
do_write = false; // No more spaces please
}
}
if (i < sentence.length()) { // Add dot if required
new_sentence += '.';
}
Trying to just make a small string reverser and when reversing the characters of a string with an odd length return, only the first and last characters of the string seem to be getting swapped:
#include <iostream>
using namespace std;
int main()
{
string word;
cout << "Word: ";
cin >> word;
if (word.length() % 2 == 0)
{
for (int i = 0; i < (word.length()/2); i++)
{
swap(word[i], word[word.length() - i - 1]);
}
}
else
{
for (int i = 0; i < (word.length()/2 - 1); i++)
{
swap(word[i], word[word.length() - i]);
}
}
cout << word << endl;
}
Your indexing logic is not correct. Look at this.
swap(word[i], word[word.length() - i]);
The loop starts with i == 0 sou you're trying to swap() characters at position i == 0 and word.length() - i == word.length() - 0 == word.length() which is out-of-bounds and therefore undefined behavior. You got that part right in the even case where you subtract 1.
Also consider what happens in the case that word.length() == 1. You check for
i < (word.length() / 2 - 1)
in the conditional of your for loop. If word.length() == 1, then word.length() / 2 == 0 and now you subtract 1 from it. This will underflow the (unsigned) integer, which is well-defined but gives you the most positive value so you'll loop over all kind of invalid indices.
In general, I think your case selection is needlessly complicated. It would be easier if you used iterators. Since you say this is an exercise for you, I won't show you the solution but you can easily find it in the web. This question gets asked here fairly often.
Here is simple code:
#include <iostream>
using namespace std;
int main()
{
string word;
cout << "Word: ";
cin >> word;
for (int i = 0; i < (word.length()/2); i++)
{
swap(word[i], word[word.length() - i - 1]);
}
cout << word << endl;
}
you do not need if/else statement.