function that tells if two strings are anagrams

Im trying to take in two strings and send them to a function that tells if they are anagrams spaces and punctuation is ignored but can be input. I am either not calling my function right or the function itself is messed up. Code is a disaster i know im just trying to get this to work

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
 #include <stdio.h>
#include <iostream>
#include <iomanip>
using namespace std;

bool anagrams(string a, string b){
	int alen = 0, blen = 0;
	string one, two;
	bool status = true;
	
	for(int i=0; i < 100; i++){
		if(a[i] != 0){
			alen++;
		}
	}
	
		for(int i=0; i < 100; i++){
		if(b[i] != 0){
			blen++;
		}
	}
	
	int x = 0, y = 0;
	
	for(int i=0; i < alen; i++){
		if(isalpha(a[i]) == true){
			a[i] = one[x];
			x++;
		}
	}
	
	for(int i=0; i < blen; i++){
		if(isalpha(b[i]) == true){
			b[i] = two[y];
			y++;
		}
	}
	
	string onerev;
	int rev = 0;
	
	for(int i = x-1; i != 0; i--){
		one[i] = onerev [rev];
		rev++;
	}
	
	for(int i = 0; i < rev; i++){
		if(onerev[i] < 97){
			onerev[i] += 32;
		}
	}
	
		for(int i = 0; i < y ; i++){
		if(two[i] < 97){
			two[i] += 32;
		}
	}
	
	if(onerev == two){
		return status;
	}
	else{
		status = false;
		return status;
	}
}

int main(){
	
	string one, two;
	
	cin >> one;
	cin >> two;
	
	if(anagrams(one, two) == true){
		cout <<"\"" <<  one <<"\"" << " is an anagram of \"" << two << "\"";
	}	
	else{
		cout << "\"" << one << "\"" << " is not an anagram of \"" << two << "\"";
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>
using namespace std;

string filter( string s )
{
   string result;
   for ( char c : s ) if ( isalnum( c ) ) result += tolower( c );
   sort( result.begin(), result.end() );
   return result;
}

bool areAnagrams( string s1, string s2 )
{
   return filter( s1 ) == filter( s2 );
}

int main()
{
   string s1 = "William Shakespeare";
   string s2 = "I am a weakish speller";
   cout << "[" << s1 << "] and [" << s2 << "] " << ( areAnagrams( s1, s2 ) ? "are" : "are not" ) << " anagrams\n";
}


[William Shakespeare] and [I am a weakish speller] are anagrams
I can only use the libraries from my first post its for an assignment. Is anyone able to try and improve my original code.
@griffingradke,
Do you know the difference between an ANAGRAM and a PALINDROME?
At risk of repeating lastchance's question:

griffingradke, your original code doesn't work - it doesn't search for anagrams. It can't be "improved" so much as "destroyed because it's doing the wrong thing". Your original code is checking for palindromes.
Last edited on
something like this:
clean up the string (remove anything not in 'a' to 'z' for english for example, including spaces) and set it to either upper or lower case letters across the board.
then call sort on the string.
repeat for second string.
compare a==b. if they do, it is an anagram. Not sure if anagrams require distinct letters or not, if not, you should deduplicate both before compare. (eg does AABBCC == ABC?)

this is like 4 lines for each string if you use c++ <algorithm>s.

something like: (its a lot to type in without checking it, but hopefully close)
1
2
3
4
std::transform(s.begin(), s.end(),s.begin(), ::toupper);      //upper case input
  s.erase(std::remove_if(s.begin(), s.end(),                     //cleanup
  [](char &c){return (c>'Z'||c<'A');}),s.end());   
std::sort(s.begin(),s.end());	                                //sort the string 


etc?
Last edited on
I can only use the libraries from my first post

Not clear if you can use the <string> library or not. You use strings, but do not include the <string> header which is required if you want to use strings.

If you're allowed to use strings, you can replace lines 11-21 with:
1
2
  alen = a.size(); 
  blen = b.size();


Both lastchance and jonin have given you the general logic to determine if two strings are anagrams. Sort each string, them compare the results for equality.
Sorting is convenient if you have a pre-written function. Other methods are easier than writing a sorting function from scratch, IMO.

Two anagrams have the same frequencies each letter. Build a frequency table of the letters in each work and compare them to see if they're the same.

1
2
3
4
5
6
7
8
9
10
11
bool anagrams(string a, string b)
{
    int aFreq[26] = {0}, bFreq[26] = {0};

    //you fill in the rest.

    for (int i = 0; i < 26; i++)
        if (aFreq[i] != bFreq[i])
            return false;
    return true;
}
Last edited on
Nice, Brownie. I knew there had to be another alternative to sorting the string itself, but I was having a mental block as to what the alternative was. That's probably what OP wants if he isn't expected to know how to sort yet. And that's linear "O(n)" instead of "O(n log n)", as well, I think. (Well, O(n * k) where k is the number of letters in your alphabet, haha).
Last edited on
and the bucket sort works both ways. you can compare all the elements against true, and you'll have the duplicates ignored match; if you compare the tables exactly, you have the exact match version. you can also clean and sort and everything in one pass with a more convoluted algorithm. One way to do that is to use the bucket idea on a 256 sized ascii array, load it via bucket[toupper(string[i])] and then compare memcpy( from 'A' to 'Z' only of the array).

Its the same logic, just different mechanics.
Last edited on
Registered users can post here. Sign in or register to post.