I need to create a program that allows a user to input a string and my program will check to see if that string they entered is a palindrome (word that can be read the same backwards as it can forwards).
Note that reversing the whole string (either with the rbegin()/rend() range constructor or with std::reverse) and comparing it with the input would perform unnecessary work.
It's sufficient to compare the first half of the string with the latter half, in reverse:
#include <string>
#include <algorithm>
#include <iostream>
int main()
{
std::string s;
std::cin >> s;
if( equal(s.begin(), s.begin() + s.size()/2, s.rbegin()) )
std::cout << "is a palindrome.\n";
else
std::cout << "is NOT a palindrome.\n";
}
demo: http://ideone.com/mq8qK
Just compare the string with itself reversed:
string input;
cout << "Please enter a string: ";
cin >> input;
if (input == string(input.rbegin(), input.rend())) {
cout << input << " is a palindrome";
}
This constructor of string takes a beginning and ending iterator and creates the string from the characters between those two iterators. Since rbegin() is the end of the string and incrementing it goes backwards through the string, the string we create will have the characters of input added to it in reverse, reversing the string.
Then you just compare it to input and if they are equal, it is a palindrome.
This does not take into account capitalisation or spaces, so you'll have to improve on it yourself.
bool IsPalindrome(const char* psz)
{
int i = 0;
int j;
if ((psz == NULL) || (psz[0] == '\0'))
{
return false;
}
j = strlen(psz) - 1;
while (i < j)
{
if (psz[i] != psz[j])
{
return false;
}
i++;
j--;
}
return true;
}
// STL string version:
bool IsPalindrome(const string& str)
{
if (str.empty())
return false;
int i = 0; // first characters
int j = str.length() - 1; // last character
while (i < j)
{
if (str[i] != str[j])
{
return false;
}
i++;
j--;
}
return true;
}
// The below C++ function checks for a palindrome and
// returns true if it is a palindrome and returns false otherwise
bool checkPalindrome ( string s )
{
// This calculates the length of the string
int n = s.length();
// the for loop iterates until the first half of the string
// and checks first element with the last element,
// second element with second last element and so on.
// if those two characters are not same, hence we return false because
// this string is not a palindrome
for ( int i = 0; i <= n/2; i++ )
{
if ( s[i] != s[n-1-i] )
return false;
}
// if the above for loop executes completely ,
// this implies that the string is palindrome,
// hence we return true and exit
return true;
}
#include <iostream>
#include <string>
bool isPalindrome(const std::string& str){
if(str.empty()) return true;
std::string::const_iterator itFirst = str.begin();
std::string::const_iterator itLast = str.end() - 1;
while(itFirst < itLast) {
if (*itFirst != *itLast)
return false;
++itFirst;
--itLast;
}
return true;
}
int main(){
while(1){
std::string input;
std::cout << "Eneter a string ...\n";
std::cin >> input;
if(isPalindrome(input)){
std::cout << input << " is palindrome.\n";
} else {
std::cout << input << " is not palindrome.\n";
}
}
return 0;
}
Check the string starting at each end and meet in the middle. Return false if there is a discrepancy.
#include <iostream>
bool palidromeCheck(std::string str) {
for (int i = 0, j = str.length()-1; i <= j; i++, j--)
if (str[i] != str[j])
return false;
return true;
}
int main(){
std::cout << palidromeCheck("mike");
std::cout << palidromeCheck("racecar");
}
Reverse the string and check if original string and reverse are same or not
I'm no c++ guy, but you should be able to get the gist from this.
public static string Reverse(string s) {
if (s == null || s.Length < 2) {
return s;
}
int length = s.Length;
int loop = (length >> 1) + 1;
int j;
char[] chars = new char[length];
for (int i = 0; i < loop; i++) {
j = length - i - 1;
chars[i] = s[j];
chars[j] = s[i];
}
return new string(chars);
}
Related
In this question, we take 2 strings as input say s1 and s2.
Now, first we need to check if s2 is a subsequence of s1. If not, print no.
But if it is, we need to print the minimum number of characters to be deleted from s1 to get s2.
Eg- thistext text
Here, text can be directly found without deleting any characters so the answer is 0.
Eg- cutefriendship crisp
In this case, the answer is 9.
What I've done so far,
#include <bits/stdc++.h>
using namespace std;
int checkIfSub(string s1, string s2, int m, int n)
{
int j = 0;
for(int i = 0; i < m && j < n; i++)
if(s1[i] == s2[j])
j++;
if(j == n)
return 0;
else
return 1;
}
int check(string s1, string s2)
{
int count = 0; string s3;
if(checkIfSub(s1, s2, s1.length(), s2.length()) == 1 || s2.length() > s1.length())
{
cout << "NO\n"; return 0;
}
int j = 0;
for(int i = 0; i < s1.length(); i++)
{
if(s1[i] == s2[j])
{
s3[j] = s1[j];
j++; continue;
}
count++;
}
cout << "YES " << count << "\n";
return 0;
}
int main() {
string s1, s2;
cin >> s1 >> s2;
check(s1, s2);
return 0;
}
My code works well for the second example, but fails the first case.
(This was a question asked in some interview I read online.)
Try something like this:
#include <iostream>
#include <string>
using namespace std;
bool check(const string &s1, const string &s2, int &minToDelete)
{
minToDelete = 0;
bool anySubSeqFound = false;
if (s2.empty())
return false;
string::size_type first = 0;
while ((first = s1.find(s2[0], first)) != string::npos)
{
int numDeleted = 0;
bool isSubSeq = true;
string::size_type next = first + 1;
for(string::size_type j = 1; j < s2.size(); ++j)
{
string::size_type found = s1.find(s2[j], next);
if (found == string::npos)
{
isSubSeq = false;
break;
}
numDeleted += (found - next);
next = found + 1;
}
if (isSubSeq)
{
if (anySubSeqFound)
{
if (numDeleted < minToDelete)
minToDelete = numDeleted;
}
else
{
anySubSeqFound = true;
minToDelete = numDeleted;
}
}
++first;
}
return anySubSeqFound;
}
int main()
{
int minToDelete;
if (check("thistext", "text", minToDelete))
cout << "yes, delete " << minToDelete << endl;
else
cout << "no" << endl;
if (check("cutefriendship", "crisp", minToDelete))
cout << "yes, delete " << minToDelete << endl;
else
cout << "no" << endl;
}
Live Demo
Hello I'm kind of new to coding and I am writing a code that deletes any duplicate characters on a string. Let's say the input string was ABBA, then the output should be "empty" since all of the duplicates were deleted. Another example would be if the input string was KKCCD, then the output should be "D" as the code would remove the K and C duplicates. The problem with my code is that when I type KKCCD, it returns KCD and it doesnt delete the duplicates entirely. Also if I we're to type "AA" the result comes back as "A" instead of "Empty". Any help in fixing my code will be much apreciated. Thanks.
include
#include <string.h>
using namespace std;
string deduplicate(string input){
int i;
int x;
int len= input.length();
string outputStr;
string strEmpty = "Empty";
if (input.length() == 1)
{return input;}
for(i = 0; i<len;i++){
for(x = i+1; x<len; x++){
if(input[i] == input[x]){
input.erase(x,1);
x--;}
}
len = input.length();
}
return outputStr = input;
if (input.length() == 0)
{return strEmpty;}
return outputStr = input;
}
int main()
{
string input;
cout << "Enter a string: " << endl;
cin >> input;
cout << deduplicate(input);
return 0;
}
Change your duplicate function to this
string deduplicate(string input){
int i;
int x;
int len= input.length();
string outputStr;
string strEmpty = "Empty";
if (input.length() == 1)
{return input;}
for(i = 0; i<len;i++){
for(x = i+1; x<input.length(); x++){ // This line
if(input[i] == input[x]){
input.erase(x,1);
input.erase(i,1); // and this line
x--;
}
}
len = input.length();
}
return outputStr = input;
if (input.length() == 0)
{return strEmpty;}
return outputStr = input;
}
You did delete the duplicate character but not original, so the second erase statement does it.
You are deleting the duplicate you find, but you never delete the original character. The most efficient way to achieve your goal is to use STL algorithms. You might want to check out this link: Remove all duplicate characters from a string (STL)
Generally speaking I do not think if that is a good idea to delete characters from a string you are iterating. It would be much better and cleaner to construct your output instead:
#include <string>
#include <iostream>
using namespace std;
string deduplicate(string input) {
string outputStr;
if (input.length() == 1) {
return input;
}
for ( int i = 0; i < input.length(); i++ ) {
// try to find character at the rest of the string
if ( input.find( input[i], i+1 ) == string::npos ) {
// try to find character in the front
if ( ( i > 0 ) && ( input.rfind( input[i], i-1 ) == string::npos ) ) {
outputStr += input[i];
}
}
}
return outputStr;
}
int main()
{
string input;
cout << "Enter a string: " << endl;
cin >> input;
cout << deduplicate(input) << endl;
return 0;
}
Here is a "brute force" implementation.
string deduplicate(string str)
{
size_t l = str.length();
bool bFound = false;
char character = 0;
for (int i = 0; i < l; i++)
{
character = str[i];
while (true)
{
size_t next = str.rfind(character);
if (next != std::string::npos)
{
if (bFound || (!bFound && next != i))
{
str.erase(next, 1);
bFound = true;
l--;
}
}
if (next == i)
{
if (bFound == true)
{
i--;
}
bFound = false;
break;
}
}
}
return str;
}
I need to create a program that allows a user to input a string and my program will check to see if that string they entered is a palindrome (word that can be read the same backwards as it can forwards).
Note that reversing the whole string (either with the rbegin()/rend() range constructor or with std::reverse) and comparing it with the input would perform unnecessary work.
It's sufficient to compare the first half of the string with the latter half, in reverse:
#include <string>
#include <algorithm>
#include <iostream>
int main()
{
std::string s;
std::cin >> s;
if( equal(s.begin(), s.begin() + s.size()/2, s.rbegin()) )
std::cout << "is a palindrome.\n";
else
std::cout << "is NOT a palindrome.\n";
}
demo: http://ideone.com/mq8qK
Just compare the string with itself reversed:
string input;
cout << "Please enter a string: ";
cin >> input;
if (input == string(input.rbegin(), input.rend())) {
cout << input << " is a palindrome";
}
This constructor of string takes a beginning and ending iterator and creates the string from the characters between those two iterators. Since rbegin() is the end of the string and incrementing it goes backwards through the string, the string we create will have the characters of input added to it in reverse, reversing the string.
Then you just compare it to input and if they are equal, it is a palindrome.
This does not take into account capitalisation or spaces, so you'll have to improve on it yourself.
bool IsPalindrome(const char* psz)
{
int i = 0;
int j;
if ((psz == NULL) || (psz[0] == '\0'))
{
return false;
}
j = strlen(psz) - 1;
while (i < j)
{
if (psz[i] != psz[j])
{
return false;
}
i++;
j--;
}
return true;
}
// STL string version:
bool IsPalindrome(const string& str)
{
if (str.empty())
return false;
int i = 0; // first characters
int j = str.length() - 1; // last character
while (i < j)
{
if (str[i] != str[j])
{
return false;
}
i++;
j--;
}
return true;
}
// The below C++ function checks for a palindrome and
// returns true if it is a palindrome and returns false otherwise
bool checkPalindrome ( string s )
{
// This calculates the length of the string
int n = s.length();
// the for loop iterates until the first half of the string
// and checks first element with the last element,
// second element with second last element and so on.
// if those two characters are not same, hence we return false because
// this string is not a palindrome
for ( int i = 0; i <= n/2; i++ )
{
if ( s[i] != s[n-1-i] )
return false;
}
// if the above for loop executes completely ,
// this implies that the string is palindrome,
// hence we return true and exit
return true;
}
#include <iostream>
#include <string>
bool isPalindrome(const std::string& str){
if(str.empty()) return true;
std::string::const_iterator itFirst = str.begin();
std::string::const_iterator itLast = str.end() - 1;
while(itFirst < itLast) {
if (*itFirst != *itLast)
return false;
++itFirst;
--itLast;
}
return true;
}
int main(){
while(1){
std::string input;
std::cout << "Eneter a string ...\n";
std::cin >> input;
if(isPalindrome(input)){
std::cout << input << " is palindrome.\n";
} else {
std::cout << input << " is not palindrome.\n";
}
}
return 0;
}
Check the string starting at each end and meet in the middle. Return false if there is a discrepancy.
#include <iostream>
bool palidromeCheck(std::string str) {
for (int i = 0, j = str.length()-1; i <= j; i++, j--)
if (str[i] != str[j])
return false;
return true;
}
int main(){
std::cout << palidromeCheck("mike");
std::cout << palidromeCheck("racecar");
}
Reverse the string and check if original string and reverse are same or not
I'm no c++ guy, but you should be able to get the gist from this.
public static string Reverse(string s) {
if (s == null || s.Length < 2) {
return s;
}
int length = s.Length;
int loop = (length >> 1) + 1;
int j;
char[] chars = new char[length];
for (int i = 0; i < loop; i++) {
j = length - i - 1;
chars[i] = s[j];
chars[j] = s[i];
}
return new string(chars);
}
#include <iostream>
#include <string>
using namespace std;
int main() {
string str_1 = "Gandalf";
string str_2 = "dal";
for (int i = 0; i <= str_1.length() - 2; i++)
for (int j = 0; j <= str_2.length(); j++) {
if (str_2[j] == str_1[i]) {
if (str_2[j + 1] == str_1[i + 1]) {
if (str_2[j + 2] == str_1[i + 2])
cout << "true";
}
}
}
return 0;
}
I can do it but if length of str_2 is 4 characters, program doesn't work.
I want that program can work for every length of string
but how?
The function find below basically reproduces the behaviour of std::string::find (without the starting position parameter). You need to:
loop through the outer string, and at each step:
loop through the second string checking each character.
If any of these fail, drop back to the outer loop.
If we make it all the way through the inner loop, then the second string is there, and return the current position in the outer loop.
If we run out of space in the first string, just skip the rest.
Hopefully the comments make this clear. I also include a little utility function to turn the found position into true/false, and some tests.
#include <iomanip>
#include <iostream>
#include <string>
std::string::size_type find(const std::string& s1,
const std::string& s2)
// return the position of s2 within s1,
// else npos if it is not present.
{
using size_type = std::string::size_type;
size_type curPos = 0;
size_type lim = s1.size();
size_type innerLim = s2.size();
for (; curPos<lim; ++curPos) { // loop through s1
if (lim < curPos+innerLim) {
break; // not enough space left
}
size_type innerPos = 0;
for(; innerPos < innerLim // loop through s2, while matching
&& curPos + innerPos < lim
&& s1[innerPos+curPos] == s2[innerPos];
++innerPos) ; // do nothing in the loop
if (innerPos == innerLim) { // matched the whole loop
return curPos;
}
}
return std::string::npos; // never matched
}
bool contains(const std::string& s1,
const std::string& s2)
{
return find(s1, s2)!=std::string::npos;
}
int main()
{
std::cout
<< std::boolalpha
<< contains("abc", "") << '\n' // true
<< contains("abc", "abc") << '\n' // true
<< contains("abc", "bc") << '\n' // true
<< contains("abc", "abcd") << '\n' // false
<< contains("abc", "abd") << '\n' // false
<< contains("abc", "xyz") << '\n';// false
}
This does more than what you really need, but it most closely models the "real" answer (use the facilities the language provides). Plus it makes it not a great homework answer, but contains all the clues to write your homework answer.
You could try something like this:
for (int i = 0; i < str_1.length() - str_2.length(); i++) {
bool is_same = true;
for (int j = 0; j < str_2.length(); j++) {
if (str[i + j] != str_2[j]) {
is_same = false;
break;
}
}
if (is_same) {
std::cout << "true" << std:endl;
}
}
It iterates over every character in str_1 and checks whether the character sequence starting at that point is the same as str_2.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Trying to implement a fairly simple program in C++. I'm kinda new to this language. But it doesn't seem to be working.
#include <iostream>
#include <string>
using namespace std;
bool isUnique(string);
int main(){
bool uniq;
string a;
cout << "Please input a string, not a very long one...."<< endl;
getline(cin, a);
uniq = isUnique(a);
if (uniq == true)
{
cout << "The string has no repeatations." <<endl;
}else{
cout << "The characters in the string are not unique." <<endl;
}
return EXIT_SUCCESS;
}
bool isUnique(string str){
int len = strlen(str);
bool uniq = true;
for (int i = 0; i <= len; ++i)
{
for (int j = i+1; j <= len; ++j)
{
if (str[j] == str[i])
{
uniq = false;
}
}
}
return uniq;
}
The program compiles but has some logical errors I suppose. Any help appreciated.
An simple criterion for uniqueness is that there are no repeated characters in the sorted range of characters. There are algorithms in the standard library for this:
#include <algorithm> // for std::sort, std::unique
#include <iostream> // for std::cin, std::cout
#include <string> // for std:getline, std::string
int main()
{
std::string input;
std::cout << "Please input a string, not a very long one: ";
std::getline(input, std::cin);
std::sort(input.begin(), input.end());
bool u = std::unique(input.begin(), input.end()) == input.end();
if (u) { std::cout << "Every character is unique.\n"; }
else { std::cout << "The string contains repeated characters.\n"; }
}
As an optimization, you can exit early if the string has more characters than there are unique characters, though you'd need some way to determine what that number is.
You can check uniqueness much easier without a nested loop: make an array of bool[256], cast char to unsigned char, and use as an index into the array. If a bool has been set, the characters are not unique; otherwise, they are unique.
bool seen[256];
for (int i = 0 ; i != str.length() ; i++) {
unsigned char index = (unsigned char)str[i];
if (seen[index]) return false;
seen[index] = true;
}
return true;
The idea is simple: you mark characters that you've seen as you go, returning false if you see a "marked" character. If you reach the end without returning, all characters are unique.
This algorithm is O(n); your algorithm is O(n2). This does not make much difference, though, because it is impossible to construct a string of unique characters that is longer than 256 characters.
You are using a string, so it is not necessary to convert it to a char array. Use the string to check. You can check it like this:
bool isUnique(string str){
for (std::string::size_type i = 0; i < str.size(); ++i)
{
if(i < str.size()-1){
for (std::string::size_type j = i+1; j < str.size(); ++j)
{
if (str[j] == str[i])
{
uniq = false;
}
}
}
}
return uniq;
}
you can try this:
int main () {
bool uniqe=false;
string a;
char arr[1024];
int count[256]={0};
cout << "Please input a string, not a very long one...."<< endl;
getline(cin, a);
strcpy(arr, a.c_str());
for(int i=0;i<strlen(arr);i++)
count[(int)(arr[i])]++; // counting the occurence of character
for(int i=0;i<256;i++){
if(count[i]>1){ // if count > 1 means character are repeated.
uniqe=false;
break;
}else{
uniqe=true;
}
}
if(uniqe)
cout << "The string has no repeatations." <<endl;
else
cout << "The characters in the string are not unique." <<endl;
return 0;
}
There are too many errors in your code. For example instead of
int len = sizeof(arr)/sizeof(*arr);
there shall be
size_t len = std::strlen( arr );
Or instead of
for (int i = 0; i <= len; ++i)
there shall be at least
for (int i = 0; i < len; ++i)
and so on.
And there is no any need to define a character array. Class std::string has all that is required to do the task.
Try the following function
bool isUnique( const std::string &s )
{
bool unique = true;
for ( std::string::size_type i = 0; i < s.size() && unique; i++ )
{
std::string::size_type j = 0;
while ( j < i && s[j] != s[i] ) ++j;
unique = j == i;
}
return unique;
}
Here is a demonstrative program
#include <iostream>
#include <iomanip>
#include <string>
bool isUnique( const std::string &s )
{
bool unique = true;
for ( std::string::size_type i = 0; i < s.size() && unique; i++ )
{
std::string::size_type j = 0;
while ( j < i && s[j] != s[i] ) ++j;
unique = j == i;
}
return unique;
}
int main()
{
std::string s( "abcdef" );
std::cout << std::boolalpha << isUnique( s ) << std::endl;
s = "abcdefa";
std::cout << std::boolalpha << isUnique( s ) << std::endl;
return 0;
}
The output is
true
false
Here is your code with the errors fixed:
#include <iostream>
using namespace std;
bool isUnique(string,int); //extra parameter
int main(){
bool uniq;
string a;
cout << "Please input a string, not a very long one...."<< endl;
getline(cin, a);
uniq = isUnique(a,a.length()); //pass length of a
if (uniq == true)
{
cout << "The string has no repeatations." <<endl;
}else{
cout << "The characters in the string are not unique." <<endl;
}
return EXIT_SUCCESS;
}
bool isUnique(string str,int len){
bool uniq = true;
for (int i = 0; i < len-1; ++i) //len-1 else j would access unitialized memory location in the last iteration
{
for (int j = i+1; j < len; ++j) //j<len because array index starts from 0
{
if (str[j] == str[i])
{
uniq = false;
}
}
}
return uniq;
}