#include "iostream"
#include "string"
#include <fstream>
#include <cctype>
using namespace std;
#define NO_OF_CHARS 256
bool checkAnagram(string a,string b);
// Function to print all pairs of anagrams
void findAllAnagrams(string str[], int n)
{
// loop for all strings from array
for (int i = 0; i < n; i++)
for (int j = i+1; j < n; j++)
if (checkAnagram(str[i], str[j])) // check if two strings are anagrams
cout << str[i] << " is anagram of " << str[j] << endl; // print if strings are anagrams
}
// function to check whether two strings are anagram or not //
bool checkAnagram(string string1, string string2)
{
// Create two count arrays and initialize all values as 0
int count[NO_OF_CHARS] = {0};
int i;
for (i = 0; string1[i] && string2[i]; i++)
{
count[string1[i]]++;
count[string2[i]]--;
}
if (string1[i] || string2[i])
return false;
for (i = 0; i < NO_OF_CHARS; i++)
if (count[i])
return false;
return true;
}
int main()
{
string string_name;
ifstream file_stream;
int count = 0;
file_stream.open("PrideAndPrejudice.txt"); // open file to read. your filename
// while loop to count number of strings
while (getline(file_stream, string_name , ' '))
{
count++;
for (int i = 0, length = string_name.size(); i < length; i++)
{
string_name[i] = tolower(string_name[i]);
// check whether parsing character is punctuation or not
if (ispunct(string_name[i]))
{
string_name.erase(i--, 1); // if punctuation is found erase that character
length = string_name.size(); // reduce size of string
}
}
}
file_stream.close();
file_stream.open("PrideAndPrejudice.txt"); // open file again to point to start of file
string wordArr[count]; // create word array to store the list of words read from file
count = 0; // initialize count to 0
while (getline(file_stream, string_name , ' '))
{
for (int i = 0, length = string_name.size(); i < length; i++)
{
string_name[i] = tolower(string_name[i]); // convert uppercase to lowercase
// check whether parsing character is punctuation or not
if (ispunct(string_name[i]))
{
string_name.erase(i--, 1);
length = string_name.size();
}
}
wordArr[count] = string_name; // store word in array
count++;
}
findAllAnagrams(wordArr, count); // check all anagrams
file_stream.close(); // close file stream
return 0;
}
My code is giving no output, am I not reading in the file correctly?
This is part of the complete solution to find anagram between to strings:
/** ASSUMES THE IMPLEMENTATION OF quicksort METHOD TO SORT THE STRINGS.
* return '1' if str1 & str2 are anagrams. '0' otherwise.
*/
int isanagram2(char *str1, char* str2)
{
// If both are NULL. Return true
if(str1 == NULL && str2 == NULL)
return true;
// If one of them is null & other not.
if(str1 == NULL || str2 == NULL || strlen(str1) != strlen(str2))
return false;
quicksort(str1);
quicksort(str2);
// Compare char-by-char
for(int i=0; str1[i] != '\0' ; i++)
if(str1[i] != str2[i])
return false;
return true;
}
Related
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);
}
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;
}
This was the interview question:
How to convert Dogs like cats to cats like Dogs ?
My code shows: cats like cats. Where am I making the mistakes?
#include <iostream>
using namespace std;
int main()
{
char sentence[] = ("dogs like cats");
cout << sentence << endl;
int len = 0;
for (int i = 0; sentence[i] != '\0'; i++)
{
len++;
}
cout << len << endl;
char reverse[len];
int k = 0;
for (int j = len - 1; j >= 0; j--)
{
reverse[k] = sentence[j];
k++;
}
cout << reverse << endl;
int words = 0;
char str[len];
for (int l = 0; reverse[l] != '\0'; l++)
{
if (reverse[l] == ' ' || reverse[l] == '\0') // not sure about this part
{
for (int m = l; m >= 0; m--)
{
str[words] = reverse[m];
words++;
}
}
}
cout << str;
return 0;
}
I know you can do this using pointers, stack, vectors... but interviewer was not interested in that!
This is a fixed version of your sample code:
Your principal problem is that every time you found and ' ' or '\0' you copy the bytes of the reverse string from the beginning to that point. Example in loop 5 you copy from index 0-5 (stac) from reverse to str in reverse order, but in in loop 10 you copy from index 0-10 (stac ekil) from reverse to str in reverse order, until here you have already the printed result string ('cats like cats'), and the same in loop 15 all of this incrementing the index of str, in the last loop you are written pass the end of the valid memory of str (and because of that not printed as output).
You need to keep track when end the last word reversed to reverse only the actual word, and not the string from the beginning to the actual index.
You don't want to count the special character (' ' and '\0') in the reversing of the words, you would end with cats like\0dogs
Modified sample code provided:
#include <iostream>
using namespace std;
int main() {
char sentence[] = ("dogs like cats");
cout << sentence << endl;
int len = 0;
for (int i = 0; sentence[i] != '\0'; i++) {
len++;
}
cout << len << endl;
char reverse[len];
int k = 0;
for (int j = len - 1; j >= 0; j--) {
reverse[k] = sentence[j];
k++;
}
cout << reverse << endl;
int words = 0;
char str[len];
// change here added last_l to track the end of the last word reversed, moved
// the check of the end condition to the end of loop body for handling the \0
// case
for (int l = 0, last_l = 0; ; l++) {
if (reverse[l] == ' ' || reverse[l] == '\0')
{
for (int m = l - 1; m >= last_l; m--) { // change here, using last_t to
str[words] = reverse[m]; // only reverse the last word
words++; // without the split character
}
last_l = l + 1; // update the end of the last
// word reversed
str[words] = reverse[l]; // copy the split character
words++;
}
if (reverse[l] == '\0') // break the loop
break;
}
cout << str << endl;
return 0;
}
Some code, written with the restriction of using the most simple features of the language.
#include <iostream>
// reverse any block of text.
void reverse(char* left, char* right) {
while (left < right) {
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main() {
char sentence[] = "dogs like cats";
std::cout << sentence << std::endl;
// The same length calculation as sample code.
int len = 0;
for (int i = 0; sentence[i] != '\0'; i++) {
len++;
}
std::cout << len << std::endl;
// reverse all the text (ex: 'stac ekil sgod')
reverse(sentence, sentence + len - 1);
// reverse word by word.
char* end = sentence;
char* begin = sentence;
while (end < sentence + len) {
if (*end != ' ')
end++;
if (end == sentence + len || *end == ' ') {
reverse(begin, end - 1);
begin = end + 1;
end = begin;
}
}
std::cout << sentence << std::endl;
return 0;
}
Dissecting your algorithm in pieces. First, you find the length of the string, not including the null char terminator. This is correct, though could be simplified.
size_t len = 0;
for (int i = 0; sentence[i] != '\0'; i++) {
len++;
}
cout << len << endl;
This could easily be written simply as:
size_t len = 0;
while (sentence[len])
++len;
Next, you reverse the entire string, but the first defect surfaces. The VLA (variable length array) you declare here, (which you don't need and shouldn't use, as it is a C++ extension and non-standard) does not account for, nor set, a terminating null-char.
char reverse[len]; // !! should be len+1
int k = 0;
for (int j = len - 1; j >= 0; j--) {
reverse[k] = sentence[j];
k++;
}
// !! Should have reverse[k] = 0; here.
cout << reverse << endl; // !! Undefined-behavior. no terminator.
This temporary buffer string is not needed at all. There is no reason you can't do this entire operation in-place. Once we calculate len correctly, you simply do something like the following to reverse the entire sequence, which retains the null char terminator in proper position:
// reverse entire sequence
int i = 0, j = len;
while (i < j--)
{
char c = sentence[i];
sentence[i++] = sentence[j];
sentence[j] = c;
}
Next we move to where you try to reverse each internal word. Again, just as before, the buffer length is not correct. It should be len+1. Worse (hard to imagine), you never remember where you left off when finding the end point of a word. That location should be the next point you start checking for, and skipping, whitespace. Without retaining that you copy from current point all the way back to the beginning of the string. which essentially blasts cats over dogs.
int words = 0;
char str[len]; // !! should be len+1
for (int l = 0; reverse[l] != '\0'; l++)
{
if (reverse[l] == ' ' || reverse[l] == '\0') // not sure about this part
{
for (int m = l; m >= 0; m--) {
str[words] = reverse[m];
words++;
}
}
}
cout << str; //!! Undefined behavior. non-terminated string.
Once again, this can be done in-place without difficulty at all. One such algorithm looks like this (and notice the loop that reverses the actual word is not-coincidentally the same algorithm as reversing our entire buffer):
// walk again, reversing each word.
i = 0;
while (sentence[i])
{
// skip ws; root 'i' at beginning of word
while (sentence[i] == ' ') // or use std::isspace(sentence[i])
++i;
// skip until ws or eos; root 'j' at one-past end of word
j = i;
while (sentence[j] && sentence[j] != ' ') // or use !std::isspace(sentence[j])
++j;
// remember the last position
size_t last = j;
// same reversal algorithm we had before
while (i < j--)
{
char c = sentence[i];
sentence[i++] = sentence[j];
sentence[j] = c;
}
// start at the termination point where we last stopped
i = last;
}
Putting It All Together
Though considerably simpler to use pointers than all these index variables, the following will do what you're attempting, in place.
#include <iostream>
int main()
{
char s[] = "dogs like cats";
std::cout << s << '\n';
size_t len = 0, i, j;
while (s[len])
++len;
// reverse entire sequence
i = 0, j = len;
while (i < j--)
{
char c = s[i]; // or use std::swap
s[i++] = s[j];
s[j] = c;
}
// walk again, reversing each word.
i = 0;
while (s[i])
{
// skip ws; root 'i' at beginning of word
while (s[i] == ' ') // or use std::isspace
++i;
// skip until ws or eos; root 'j' at one-past end of word
j = i;
while (s[j] && s[j] != ' ') // or use !std::isspace
++j;
// remember the last position
size_t last = j;
while (i < j--)
{
char c = s[i]; // or use std::swap
s[i++] = s[j];
s[j] = c;
}
// start at last-left posiion
i = last;
}
std::cout << s << '\n';
return 0;
}
Output
dogs like cats
cats like dogs
My advise would be to break up the original string into an array of words, reverse that array. Then add those words to your reversed sentence with a space in between.
Since they asked for no libraries, I assumed no std::string, no vectors, nothing at all and so I wrote it in C.. the only thing used is printf. Everything else is from scratch :l
The idea is that you reverse the array first. Then split the array by space and reverse each word.
Example: http://ideone.com/io6Bh9
Code:
#include <stdio.h>
int strlen(const char* s)
{
int l = 0;
while (*s++) ++l;
return l;
}
void reverse(char* str)
{
int i = 0, j = strlen(str) - 1;
for(; i < j; ++i, --j)
{
str[i] ^= str[j];
str[j] ^= str[i];
str[i] ^= str[j];
}
}
void nulltok(char* str, char tok, int* parts)
{
int i = 0, len = strlen(str);
*parts = 1;
for (; i < len; ++i)
{
if (str[i] == tok)
{
str[i] = '\0';
++(*parts);
}
}
}
char* reverse_sentence(char* str)
{
char* tmp = str;
reverse(str);
int i = 0, parts = 0, len = strlen(str);
nulltok(str, 0x20, &parts);
while(parts--)
{
reverse(str);
str += strlen(str) + 1;
}
for(; i < len; ++i)
if (tmp[i] == '\0')
tmp[i] = 0x20;
return tmp;
}
int main(void)
{
char str[] = "dogs like cats";
printf("%s", reverse_sentence(str));
return 0;
}
My solution
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
string str;
cout<<"enter the sentence"<<endl;
getline(cin,str);
char* pch;
pch = strtok((char*)str.c_str()," ");
string rev = "";
while(NULL != pch)
{
rev.insert(0,pch);
rev.insert(0," ");
pch = strtok(NULL," ");
}
cout<<"the reversed string is :"<<rev<<endl;
return 0;
}
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);
}
Given 2 strings, design a function that can check whether they are rotations to each other without making any changes on them ? The return value is boolean.
e.g ABCD, ABDC, they are not rotations. return false
ABCD, CDAB or DABC are rotations. return true.
My solution:
shift one of them to right or left one position and then compare them at each iteration.
If they are not equal at all iterations, return false. Otherwise, return true.
It is O(n). Are there other more efficient solutions ?
What if the contents of them cannot be changed ?
thanks
Concatenate the given string with the given string.
Search for the target string in the concatenated string.
Example:
Given = CDAB
After step 1, Concatenated = CDABCDAB
After step 2, Success CDABCDAB
^^^^
Rather than shifting one of them, it might be more efficient to use two index variables. Start one at 0 each time and the other at each of the possible positions (0 to N-1) and increment it mod N.
If you can't modify the strings, just take the first character of string1 and compare it to each character of string2. When you get a match, compare the second char of string1 to the next char of string2, and so on.
Pseudocode:
len = strlen(string1);
len2 = strlen(string2);
if( len != len2 )
printf("Nope.");
for( int i2=0; i2 < len; i2++ ) {
for( int i1=0; i1<len; i1++ ) {
if( string1[i1] != string2[(i2+i1)%len] )
break;
}
if( i1 == len ) {
print("Yup.");
break;
}
}
A simple one would be:
(s1+s1).find(s2) != string::npos && s1.size() == s2.size();
#include <iostream>
#include <cstring>
#include<string>
using namespace std;
void CompareString(string, string, int);
int ComputeStringLength(string str);
int main()
{
string str = ""; string str1 = ""; int len = 0, len1 = 0;
cout << "\nenter string ";
cin >> str;
cout << "\nenter string 2 to compare:- ";
cin >> str1;
len = ComputeStringLength(str);
len1 = ComputeStringLength(str1);
if (len == len1)
CompareString(str, str1, len);
else
cout << "rotation not possible";
getchar();
return 0;
}
int ComputeStringLength(string str)
{
int len = 0;
for (int i = 0; str[i] != '\0'; i++)
{
len++;
}
return len;
}
void CompareString(string str, string str1, int n)
{
int index = 0, flag = 0, curr_index = 0, count1 = 0, flagj = 0;
for (int i = 0; i<n; i++)
{
for (int j = flagj; j<n; j++)
{
if (str[i] == str1[j])
{
index = j;
flagj =j;
count1++;
flag++;
if (flag == 1)
{
curr_index = index;
}
break;
}
}
}
int temp = count1;
if (count1 != n)
{
if (curr_index>=0)
{
int k = 0;
for (int i = n - 1; i>n - curr_index - 1; i--)
{
if (str[i] == str1[k])
{
temp++;
k++;
}
}
}
if (temp == n)
{
cout << "\n\nstring is same after rotation";
}
else
{
cout << "\n\nstring is not same after rotation";
}
}
else
{
cout << "\n\nstring is same after rotation";
}
}
https://dsconceptuals.blogspot.in/2016/10/a-program-to-check-if-strings-are.html