Sub-sequence of characters - c++

Here have to find the sebsequence of characters in 2 strings..
1st string is "stackoverflow"
2nd string is user input which contains may or may not the string-1 as a sub-sequence of characters.
i.e.,stdachfdkoverrfloow it contains string1 data as a subsequence characters then output should display YES
i.e., "stackoverway" it does not contains string1 data as a subsequence characters then output should display NO
Here is my code..
#include <bits/stdc++.h>
#include<iostream>
#include<cstring>
using namespace std;
bool SubSeq(char str1[], char str2[], int m, int n)
{
if (m == 0)
return true;
if (n == 0)
return false;
if (str1[m-1] == str2[n-1])
return SubSeq(str1, str2, m-1, n-1);
return SubSeq(str1, str2, m, n-1);
}
int main()
{
int q;
cin >> q;
for(int a0 = 0; a0 < q; a0++)
{
char str1[] = "stackoverflow";
int m = strlen(str1);
char str2[] = "";
cin >> str2;
int n = strlen(str2);
SubSeq(str1, str2, m, n) ? cout << "YES\n" : cout << "NO\n";
}
return 0;
}
In the above code i am getting the output as follows..
YES
NO
NO
NO
NO
NO
NO
NO .......(truncated)
I don't know why this NO occurs so many times..Can anyone tell me where i have done a wrong step..
Thanks in advance
Venkatesh

You declare str2 as empty and then try to store the input into it.Use std::string
char str1[] = "stackoverflow";
int m = strlen(str1);
char str2[] = ""; //Notice the size of str2
cin >> str2;
You can also follow the below approach
Keep on searching for the first character of to_be_searched in search_here.When found say at i position, continue from i+1 position for the second character of to_be_searched and son on.
bool check(string to_be_Searched,string search_here)
{
for(int i=0,j=0;j<to_be_searched.length() && i<search_here.length();i++)
{
if(to_be_Searched[j]==search_here[i])
j++;
}
return j==to_be_searched.length();
}

Related

Writing a function to check the closeness of the strings

I am writing a function which will check the closeness of 2 strings. What I mean by closeness is:
strings "bat" and "bot" are 1 character apart, so the function should return 1. strings "dog" and "bot" are 2 characters apart, so the function should return 2(the 'd' vs 'b' and the 'g' vs 't'). strings "very good boy john" and "very good bot john" are just 1 character apart.
The length of 2 strings will always be the same.
I was not getting the desired output .My code for the following was:
int main(){
string a = "dog";
string b = "bot";
int index = 0;
int tot = std::count_if(a.begin(), a.end(), [&](char ch){
if(ch != b[index]){return true;}
return false;
index+=1;
});
std::cout << tot; //expected 2 but not getting 2 :(
}
Any help?
Just needed to b[index++]
.Because the index+=1 is not getting executed.
A different algorithm does the work for you.
(untested)
int main(){
string a = "dog";
string b = "bot";
int tot = std::inner_product(a.begin(), a.end(), b.begin(), 0,
std::plus<>(), std::not_equal_to<>());
std::cout << tot;
}
Requires that a and b are equal length or a is shortest
#include <iostream>
using namespace std;
// Function to count the valid indices pairs
int pairs(string str1, int size1, string str2, int size2){
// f1 and f2 for frequencies of characters
// of string str1 and str2
int f1[26] = { 0 };
int f2[26] = { 0 };
// 'c' To count the valid pairs
int i, c = 0;
//updating the frequencies of str1 and st2
for (i = 0; i < size1; i++){
f1[str1[i] - 'a']++;
}
for (i = 0; i < size2; i++){
f2[str2[i] - 'a']++;
}
// Find the count of valid pairs
for (i = 0; i < 26; i++){
c += (min(f1[i], f2[i]));
}
return c;
}
// main function
int main(){
string str1 = "tutorialspoint", str2 = "codingground";
int size1 = str1.length(), size2 = str2.length();
cout<<”Total pairs with str1[i]=str2[j] are: ”;
cout << pairs(str1, size1, str2, size2);
return 0;
}
Reference : https://www.tutorialspoint.com/count-common-characters-in-two-strings-in-cplusplus

How to print string involved in Longest common sub sequence using Recursion?

I have a code for "Longest Common Sub sequence" but I want not only longest length but also string involved in it using recursion.
Any help will be appreciated.
The below code will give only Longest length.
#include<iostream>
#include<string>
using namespace std;
int longest_seq( string s1, string s2, int n1, int n2)
{
if( n1 < 0 || n2 < 0)
return 0;
// If last char of both the string matches
if( s1[n1] == s2[n2])
return ( 1 + longest_seq(s1, s2, n1-1, n2-1));
else
return max(longest_seq(s1, s2, n1-1, n2),longest_seq(s1, s2, n1, n2-1));
}
int main()
{
string s1 = "AGGTAB";
string s2 = "GXTXAYB";
int n1 = s1.length();
int n2 = s2.length();
cout <<longest_seq(s1, s2, n1-1, n2-1);
return 0;
}
current output :
4
Expected output:
4
GTAB
One crude way of doing thing would be to pass an empty string in the longest_seq() function which will populate the string with common sub sequence.
Basically you do it like this -
int main()
{
string s1 = "AGGTAB";
string s2 = "GXTXAYB";
string out;
int n1 = s1.length();
int n2 = s2.length();
// Pass out as an input param
cout <<longest_seq(s1, s2, n1-1, n2-1, out) << endl;
cout << out << endl;
return 0;
}
You need to change longest_seq() too.
int longest_seq( string s1, string s2, int n1, int n2, string& out)
{
if( n1 < 0 || n2 < 0)
return 0;
// If last char of both the string matches
if( s1[n1] == s2[n2]) {
out.insert(0, 1, s1[n1]); // Push the matching character in front
return ( 1 + longest_seq(s1, s2, n1-1, n2-1, out));
} else {
string out1, out2; // temporary strings
int len1 = longest_seq(s1, s2, n1-1, n2, out1);
int len2 = longest_seq(s1, s2, n1, n2-1, out2);
out.insert(0, len1>len2 ? out1 : out2); // Add the correct one to the front
return max(len1, len2);
}
}
Output:
4
GTAB
You can also change the function to return the string instead of passing the output string as an argument. Then after the function returns you can easily check the length of the output of the function to get longest common subsequence length. You can easily make the necessary changes for that.

Compute the length of a longest common substring of two given 0 - 1 strings

Full title:
"Compute the length of a longest common sub-string of two given 0 - 1 strings. Input format has at least two test cases, each consisting of two non-empty 0-1 strings of lengths at most 100.The input terminates on EOF"
Here is one of my Homework, I did found out the way to compute the length of a longest common sub-string of two given 0-1 strings but I don't know how to input many test cases at ones.
Please help me if you guys have any solution for this problem.
This is my code :
#include <string>
using namespace std;
string A,B;
int lcs(int i, int j, int count)
{
if (i == 0 || j == 0)
return count;
if (A[i-1] == B[j-1])
{
count = lcs(i - 1, j - 1, count + 1);
}
count = max(count, max(lcs( i, j - 1, 0), lcs( i - 1, j, 0)));
return count;
}
int main()
{
int n,m;
cout << "Input String A and B \n";
cin >> A; cin >> B;
n=A.size();
m=B.size();
cout<< "Longest common substring "<< lcs(n,m,0) << endl;
return 0;
}
int solveYourProblemFunc(string str1, string str2) {
/* your code */
}
int main() {
int testCount;
cin >> testCount;
vector<int> results;
while(testCount--) {
string str1, str2;
getline(cin, str1);
getline(cin, str2);
int res = solveYourProblemFunc();
results.push_back(res);
}
/* output results */
}

Check whether two strings are anagrams using C++

The program below I came up with for checking whether two strings are anagrams. Its working fine for small string but for larger strings ( i tried : listened , enlisted ) Its giving me a 'no !'
Help !
#include<iostream.h>
#include<string.h>
#include<stdio.h>
int main()
{
char str1[100], str2[100];
gets(str1);
gets(str2);
int i,j;
int n1=strlen(str1);
int n2=strlen(str2);
int c=0;
if(n1!=n2)
{
cout<<"\nThey are not anagrams ! ";
return 0;
}
else
{
for(i=0;i<n1;i++)
for(j=0;j<n2;j++)
if(str1[i]==str2[j])
++c;
}
if(c==n1)
cout<<"yes ! anagram !! ";
else
cout<<"no ! ";
system("pause");
return 0;
}
I am lazy, so I would use standard library functionality to sort both strings and then compare them:
#include <string>
#include <algorithm>
bool is_anagram(std::string s1, std::string s2)
{
std::sort(s1.begin(), s1.end());
std::sort(s2.begin(), s2.end());
return s1 == s2;
}
A small optimization could be to check that the sizes of the strings are the same before sorting.
But if this algorithm proved to be a bottle-neck, I would temporarily shed some of my laziness and compare it against a simple counting solution:
Compare string lengths
Instantiate a count map, std::unordered_map<char, unsigned int> m
Loop over s1, incrementing the count for each char.
Loop over s2, decrementing the count for each char, then check that the count is 0
The algorithm also fails when asked to find if aa and aa are anagrams. Try tracing the steps of the algorithm mentally or in a debugger to find why; you'll learn more that way.
By the way.. The usual method for finding anagrams is counting how many times each letter appears in the strings. The counts should be equal for each letter. This approach has O(n) time complexity as opposed to O(n²).
bool areAnagram(char *str1, char *str2)
{
// Create two count arrays and initialize all values as 0
int count1[NO_OF_CHARS] = {0};
int count2[NO_OF_CHARS] = {0};
int i;
// For each character in input strings, increment count in
// the corresponding count array
for (i = 0; str1[i] && str2[i]; i++)
{
count1[str1[i]]++;
count2[str2[i]]++;
}
// If both strings are of different length. Removing this condition
// will make the program fail for strings like "aaca" and "aca"
if (str1[i] || str2[i])
return false;
// Compare count arrays
for (i = 0; i < NO_OF_CHARS; i++)
if (count1[i] != count2[i])
return false;
return true;
}
I see 2 main approaches below:
Sort then compare
Count the occurrences of each letter
It's interesting to see that Suraj's nice solution got one point (by me, at the time of writing) but a sort one got 22. The explanation is that performance wasn't in people's mind - and that's fine for short strings.
The sort implementation is only 3 lines long, but the counting one beats it square for long strings. It is much faster (O(N) versus O(NlogN)).
Got the following results with 500 MBytes long strings.
Sort - 162.8 secs
Count - 2.864 secs
Multi threaded Count - 3.321 secs
The multi threaded attempt was a naive one that tried to double the speed by counting in separate threads, one for each string. Memory access is the bottleneck and this is an example where multi threading makes things a bit worse.
I would be happy to see some idea that would speed up the count solution (think by someone good with memory latency issues, caches).
#include<stdio.h>
#include<string.h>
int is_anagram(char* str1, char* str2){
if(strlen(str1)==strspn(str1,str2) && strlen(str1)==strspn(str2,str1) &&
strlen(str1)==strlen(str2))
return 1;
return 0;
}
int main(){
char* str1 = "stream";
char* str2 = "master";
if(is_anagram(str1,str2))
printf("%s and %s are anagram to each other",str1,str2);
else
printf("%s and %s are not anagram to each other",str1,str2);
return 0;
}
#include<iostream>
#include<unordered_map>
using namespace std;
int checkAnagram (string &str1, string &str2)
{
unordered_map<char,int> count1, count2;
unordered_map<char,int>::iterator it1, it2;
int isAnagram = 0;
if (str1.size() != str2.size()) {
return -1;
}
for (unsigned int i = 0; i < str1.size(); i++) {
if (count1.find(str1[i]) != count1.end()){
count1[str1[i]]++;
} else {
count1.insert(pair<char,int>(str1[i], 1));
}
}
for (unsigned int i = 0; i < str2.size(); i++) {
if (count2.find(str2[i]) != count2.end()) {
count2[str2[i]]++;
} else {
count2.insert(pair<char,int>(str2[i], 1));
}
}
for (unordered_map<char, int>::iterator itUm1 = count1.begin(); itUm1 != count1.end(); itUm1++) {
unordered_map<char, int>::iterator itUm2 = count2.find(itUm1->first);
if (itUm2 != count2.end()) {
if (itUm1->second != itUm2->second){
isAnagram = -1;
break;
}
}
}
return isAnagram;
}
int main(void)
{
string str1("WillIamShakespeare");
string str2("IamaWeakishSpeller");
cout << "checkAnagram() for " << str1 << "," << str2 << " : " << checkAnagram(str1, str2) << endl;
return 0;
}
It's funny how sometimes the best questions are the simplest.
The problem here is how to deduce whether two words are anagrams - a word being essentially an unsorted multiset of chars.
We know we have to sort, but ideally we'd want to avoid the time-complexity of sort.
It turns out that in many cases we can eliminate many words that are dissimilar in linear time by running through them both and XOR-ing the character values into an accumulator. The total XOR of all characters in both strings must be zero if both strings are anagrams, regardless of ordering. This is because anything xored with itself becomes zero.
Of course the inverse is not true. Just because the accumulator is zero does not mean we have an anagram match.
Using this information, we can eliminate many non-anagrams without a sort, short-circuiting at least the non-anagram case.
#include <iostream>
#include <string>
#include <algorithm>
//
// return a sorted copy of a string
//
std::string sorted(std::string in)
{
std::sort(in.begin(), in.end());
return in;
}
//
// check whether xor-ing the values in two ranges results in zero.
// #pre first2 addresses a range that is at least as big as (last1-first1)
//
bool xor_is_zero(std::string::const_iterator first1,
std::string::const_iterator last1,
std::string::const_iterator first2)
{
char x = 0;
while (first1 != last1) {
x ^= *first1++;
x ^= *first2++;
}
return x == 0;
}
//
// deduce whether two strings are the same length
//
bool same_size(const std::string& l, const std::string& r)
{
return l.size() == r.size();
}
//
// deduce whether two words are anagrams of each other
// I have passed by const ref because we may not need a copy
//
bool is_anagram(const std::string& l, const std::string& r)
{
return same_size(l, r)
&& xor_is_zero(l.begin(), l.end(), r.begin())
&& sorted(l) == sorted(r);
}
// test
int main() {
using namespace std;
auto s1 = "apple"s;
auto s2 = "eppla"s;
cout << is_anagram(s1, s2) << '\n';
s2 = "pppla"s;
cout << is_anagram(s1, s2) << '\n';
return 0;
}
expected:
1
0
Try this:
// Anagram. Two words are said to be anagrams of each other if the letters from one word can be rearranged to form the other word.
// From the above definition it is clear that two strings are anagrams if all characters in both strings occur same number of times.
// For example "xyz" and "zxy" are anagram strings, here every character 'x', 'y' and 'z' occur only one time in both strings.
#include <map>
#include <string>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
bool IsAnagram_1( string w1, string w2 )
{
// Compare string lengths
if ( w1.length() != w2.length() )
return false;
sort( w1.begin(), w1.end() );
sort( w2.begin(), w2.end() );
return w1 == w2;
}
map<char, size_t> key_word( const string & w )
{
// Declare a map which is an associative container that will store a key value and a mapped value pairs
// The key value is a letter in a word and the maped value is the number of times this letter appears in the word
map<char, size_t> m;
// Step over the characters of string w and use each character as a key value in the map
for ( auto & c : w )
{
// Access the mapped value directly by its corresponding key using the bracket operator
++m[toupper( c )];
}
return ( m );
}
bool IsAnagram_2( const string & w1, const string & w2 )
{
// Compare string lengths
if ( w1.length() != w2.length() )
return false;
return ( key_word( w1 ) == key_word( w2 ) );
}
bool IsAnagram_3( const string & w1, const string & w2 )
{
// Compare string lengths
if ( w1.length() != w2.length() )
return false;
// Instantiate a count map, std::unordered_map<char, unsigned int> m
unordered_map<char, size_t> m;
// Loop over the characters of string w1 incrementing the count for each character
for ( auto & c : w1 )
{
// Access the mapped value directly by its corresponding key using the bracket operator
++m[toupper(c)];
}
// Loop over the characters of string w2 decrementing the count for each character
for ( auto & c : w2 )
{
// Access the mapped value directly by its corresponding key using the bracket operator
--m[toupper(c)];
}
// Check to see if the mapped values are all zeros
for ( auto & c : w2 )
{
if ( m[toupper(c)] != 0 )
return false;
}
return true;
}
int main( )
{
string word1, word2;
cout << "Enter first word: ";
cin >> word1;
cout << "Enter second word: ";
cin >> word2;
if ( IsAnagram_1( word1, word2 ) )
cout << "\nAnagram" << endl;
else
cout << "\nNot Anagram" << endl;
if ( IsAnagram_2( word1, word2 ) )
cout << "\nAnagram" << endl;
else
cout << "\nNot Anagram" << endl;
if ( IsAnagram_3( word1, word2 ) )
cout << "\nAnagram" << endl;
else
cout << "\nNot Anagram" << endl;
system("pause");
return 0;
}
In this approach I took care of empty strings and repeated characters as well. Enjoy it and comment any limitation.
#include <iostream>
#include <map>
#include <string>
using namespace std;
bool is_anagram( const string a, const string b ){
std::map<char, int> m;
int count = 0;
for (int i = 0; i < a.length(); i++) {
map<char, int>::iterator it = m.find(a[i]);
if (it == m.end()) {
m.insert(m.begin(), pair<char, int>(a[i], 1));
} else {
m[a[i]]++;
}
}
for (int i = 0; i < b.length(); i++) {
map<char, int>::iterator it = m.find(b[i]);
if (it == m.end()) {
m.insert(m.begin(), pair<char, int>(b[i], 1));
} else {
m[b[i]]--;
}
}
if (a.length() <= b.length()) {
for (int i = 0; i < a.length(); i++) {
if (m[a[i]] >= 0) {
count++;
} else
return false;
}
if (count == a.length() && a.length() > 0)
return true;
else
return false;
} else {
for (int i = 0; i < b.length(); i++) {
if (m[b[i]] >= 0) {
count++;
} else {
return false;
}
}
if (count == b.length() && b.length() > 0)
return true;
else
return false;
}
return true;
}
Check if the two strings have identical counts for each unique char.
bool is_Anagram_String(char* str1,char* str2){
int first_len=(int)strlen(str1);
int sec_len=(int)strlen(str2);
if (first_len!=sec_len)
return false;
int letters[256] = {0};
int num_unique_chars = 0;
int num_completed_t = 0;
for(int i=0;i<first_len;++i){
int char_letter=(int)str1[i];
if(letters[char_letter]==0)
++num_unique_chars;
++letters[char_letter];
}
for (int i = 0; i < sec_len; ++i) {
int c = (int) str2[i];
if (letters[c] == 0) { // Found more of char c in t than in s.
return false;
}
--letters[c];
if (letters[c] == 0) {
++num_completed_t;
if (num_completed_t == num_unique_chars) {
// it’s a match if t has been processed completely
return i == sec_len - 1;
}
}
}
return false;}
#include <iostream>
#include <string.h>
using namespace std;
const int MAX = 100;
char cadA[MAX];
char cadB[MAX];
bool chrLocate;
int i,m,n,j, contaChr;
void buscaChr(char [], char []);
int main() {
cout << "Ingresa CadA: ";
cin.getline(cadA, sizeof(cadA));
cout << "Ingresa CadB: ";
cin.getline(cadB, sizeof(cadA));
if ( strlen(cadA) == strlen(cadB) ) {
buscaChr(cadA,cadB);
} else {
cout << "No son Anagramas..." << endl;
}
return 0;
}
void buscaChr(char a[], char b[]) {
j = 0;
contaChr = 0;
for ( i = 0; ( (i < strlen(a)) && contaChr < 2 ); i++ ) {
for ( m = 0; m < strlen(b); m++ ) {
if ( a[i] == b[m]) {
j++;
contaChr++;
a[i] = '-';
b[m] = '+';
} else { contaChr = 0; }
}
}
if ( j == strlen(a)) {
cout << "SI son Anagramas..." << endl;
} else {
cout << "No son Anagramas..." << endl;
}
}
Your algorithm is incorrect. You're checking each character in the first word to see how many times that character appears in the second word. If the two words were 'aaaa', and 'aaaa', then that would give you a count of 16. A small alteration to your code would allow it to work, but give a complexity of N^2 as you have a double loop.
for(i=0;i<n1;i++)
for(j=0;j<n2;j++)
if(str1[i]==str2[j])
++c, str2[j] = 0; // 'cross off' letters as they are found.
I done some tests with anagram comparisons. Comparing two strings of 72 characters each (the strings are always true anagrams to get maximum number of comparisons), performing 256 same-tests with a few different STL containers...
template<typename STORAGE>
bool isAnagram(const string& s1, const string& s2, STORAGE& asciiCount)
{
for(auto& v : s1)
{
asciiCount[v]++;
}
for(auto& v : s2)
{
if(--asciiCount[static_cast<unsigned char>(v)] == -1)
{
return false;
}
}
return true;
}
Where STORAGE asciiCount =
map<char, int> storage; // 738us
unordered_map<char, int> storage; // 260us
vector<int> storage(256); // 43us
// g++ -std=c++17 -O3 -Wall -pedantic
This is the fastest I can get.
These are crude tests using coliru online compiler + and std::chrono::steady_clock::time_point for measurements, however they give a general idea of performance gains.
vector has the same performance, uses only 256 bytes, although strings are limited to 255 characters in length (also change to: --asciiCount[static_cast(v)] == 255 for unsigned char counting).
Assuming vector is the fastest. An improvement would be to just allocate a C style array unsigned char asciiCount[256]; on the stack (since STL containers allocate their memory dynamically on the heap)
You could probably reduce this storage to 128 bytes, 64 or even 32 bytes (ascii chars are typically in range 0..127, while A-Z+a-z 64.127, and just upper or lower case 64..95 or 96...127) although not sure what gains would be found from fitting this inside a cache line or half.
Any better ways to do this? For Speed, Memory, Code Elegance?
1. Simple and fast way with deleting matched characters
bool checkAnagram(string s1, string s2) {
for (char i : s1) {
unsigned int pos = s2.find(i,0);
if (pos != string::npos) {
s2.erase(pos,1);
} else {
return false;
}
}
return s2.empty();
}
2. Conversion to prime numbers. Beautiful but very expensive, requires special Big Integer type for long strings.
// https://en.wikipedia.org/wiki/List_of_prime_numbers
int primes[255] = {2, 3, 5, 7, 11, 13, 17, 19, ... , 1613};
bool checkAnagramPrimes(string s1, string s2) {
long c1 = 1;
for (char i : s1) {
c1 = c1 * primes[i];
}
long c2 = 1;
for (char i : s2) {
c2 = c2 * primes[i];
if (c2 > c1) {
return false;
}
}
return c1 == c2;
}
string key="listen";
string key1="silent";
string temp=key1;
int len=0;
//assuming both strings are of equal length
for (int i=0;i<key.length();i++){
for (int j=0;j<key.length();j++){
if(key[i]==temp[j]){
len++;
temp[j] = ' ';//to deal with the duplicates
break;
}
}
}
cout << (len==key.length()); //if true: means the words are anagrams
Instead of using dot h header which is deprecated in modern c++.
Try this solution.
#include <iostream>
#include <string>
#include <map>
int main(){
std::string word_1 {};
std::cout << "Enter first word: ";
std::cin >> word_1;
std::string word_2 {};
std::cout << "Enter second word: ";
std::cin >> word_2;
if(word_1.length() == word_2.length()){
std::map<char, int> word_1_map{};
std::map<char, int> word_2_map{};
for(auto& c: word_1)
word_1_map[std::tolower(c)]++;
for(auto& c: word_2)
word_2_map[std::tolower(c)]++;
if(word_1_map == word_2_map){
std::cout << "Anagrams" << std::endl;
}
else{
std::cout << "Not Anagrams" << std::endl;
}
}else{
std::cout << "Length Mismatch" << std::endl;
}
}
#include <bits/stdc++.h>
using namespace std;
#define NO_OF_CHARS 256
int main()
{ bool ans = true;
string word1 = "rest";
string word2 = "tesr";
unordered_map<char,int>maps;
for(int i = 0 ; i <5 ; i++)
{
maps[word1[i]] +=1;
}
for(int i = 0 ; i <5 ; i++)
{
maps[word2[i]]-=1 ;
}
for(auto i : maps)
{
if(i.second!=0)
{
ans = false;
}
}
cout<<ans;
}
Well if you don't want to sort than this code will give you perfect output.
#include <iostream>
using namespace std;
int main(){
string a="gf da";
string b="da gf";
int al,bl;
int counter =0;
al =a.length();
bl =b.length();
for(int i=0 ;i<al;i++){
for(int j=0;j<bl;j++){
if(a[i]==b[j]){
if(j!=bl){
b[j]=b[b.length()-counter-1];
bl--;
counter++;
break;
}else{
bl--;
counter++;
}
}
}
}
if(counter==al){
cout<<"true";
}
else{
cout<<"false";
}
return 0;
}
Here is the simplest and fastest way to check for anagrams
bool anagram(string a, string b) {
int a_sum = 0, b_sum = 0, i = 0;
while (a[i] != '\0') {
a_sum += (int)a[i]; // (int) cast not necessary
b_sum += (int)b[i];
i++;
}
return a_sum == b_sum;
}
Simply adds the ASCII values and checks if the sums are equal.
For example:
string a = "nap" and string b = "pan"
a_sum = 110 + 97 + 112 = 319
b_sum = 112 + 97 + 110 = 319

producing all anagrams in a string c++

I saw this problem online, and I was trying to solve it in C++. I have the following algorithm:
char permutations( const char* word ){
int size = strlen( word );
if( size <= 1 ){
return word;
}
else{
string output = word[ 0 ];
for( int i = 0; i < size; i++ ){
output += permutations( word );
cout << output << endl;
output = word[ i ];
}
}
return "";
}
For example, if I have abc as my input, I want to display abc, acb, bac, bca, cab, cba.
So, what I'm trying to do is
'abc' => 'a' + 'bc' => 'a' + 'b' + 'c'
=> 'a' + 'c' + 'b'
so I need o pass a word less char every function call.
Could someone please help how to do it?
I suggest doing it using the algorithm header library in C++, much easier; and as a function can be written like this:
void anagram(string input){
sort(input.begin(), input.end());
do
cout << input << endl;
while(next_permutation(input.begin(), input.end()));
}
However since you want it without the STL, you can do it like so:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void swap (char *x, char *y)
{
char ch = *x;
*x = *y;
*y = ch;
};
void permutate_(char* str, size_t index )
{
size_t i = 0;
size_t slen = strlen(str);
char lastChar = 0;
if (index == slen )
{
puts(str);
return;
}
for (i = index; i < slen; i++ )
{
if (lastChar == str[i])
continue;
else
lastChar = str[i];
swap(str+index, str+i);
permutate_(str, index + 1);
swap(str+index, str+i);
}
}
// pretty lame, but effective, comparitor for determining winner
static int cmpch(const void * a, const void * b)
{
return ( *(char*)a - *(char*)b );
}
// loader for real permutor
void permutate(char* str)
{
qsort(str, strlen(str), sizeof(str[0]), cmpch);
permutate_(str, 0);
}
Which you can call by sending it a sorted array of characters,
permutate("Hello World");
The non-STL approach was gotten from here.
The STL is wonderful:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void permutations(const char *word) {
string s = word;
sort(s.begin(), s.end());
cout << s << endl;
while(next_permutation(s.begin(), s.end()))
cout << s << endl;
}
int main() {
permutations("abc");
return 0;
}
Now, next_permutation can be implemented quite simply. From the end of the string, iterate backwards until you find an element x which is less than the next element. Swap x with the next value larger than x in the remainder of the string, and reverse the elements coming afterwards. So, abcd becomes abdc since c < d; cdba becomes dabc since c < d and we flip the last three letters of dcba; bdca becomes cabd because b < d and we swap b for c.