Skip to content

Commit 8913a01

Browse files
aniliitb10Fleshgrinder
authored andcommitted
Added C++ Anagram Detection (#119)
1 parent 8a36a20 commit 8913a01

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#include <iostream>
2+
#include <unordered_map>
3+
4+
// map of all upper case and lower case chars with prime numbers
5+
const static std::unordered_map<char, int> hash{
6+
{'a' , 2},
7+
{'b' , 3},
8+
{'c' , 5},
9+
{'d' , 7},
10+
{'e' , 11},
11+
{'f' , 13},
12+
{'g' , 17},
13+
{'h' , 19},
14+
{'i' , 23},
15+
{'j' , 29},
16+
{'k' , 31},
17+
{'l' , 37},
18+
{'m' , 41},
19+
{'n' , 43},
20+
{'o' , 47},
21+
{'p' , 53},
22+
{'q' , 59},
23+
{'r' , 61},
24+
{'s' , 67},
25+
{'t' , 71},
26+
{'u' , 73},
27+
{'v' , 79},
28+
{'w' , 83},
29+
{'x' , 89},
30+
{'y' , 97},
31+
{'z' , 101},
32+
{'A' , 103},
33+
{'B' , 107},
34+
{'C' , 109},
35+
{'D' , 113},
36+
{'E' , 127},
37+
{'F' , 131},
38+
{'G' , 137},
39+
{'H' , 139},
40+
{'I' , 149},
41+
{'J' , 151},
42+
{'K' , 163},
43+
{'L' , 167},
44+
{'M' , 173},
45+
{'N' , 179},
46+
{'O' , 181},
47+
{'P' , 191},
48+
{'Q' , 193},
49+
{'R' , 197},
50+
{'S' , 199},
51+
{'T' , 211},
52+
{'U' , 223},
53+
{'V' , 227},
54+
{'W' , 229},
55+
{'X' , 233},
56+
{'Y' , 239},
57+
{'Z' , 241 }
58+
};
59+
60+
// returns the hash of string which is unique for the combination
61+
// of characters in that string.
62+
// By unique factorization theorem there won't be any hash collisions
63+
long long get_hash(const std::string& str) {
64+
long long hash_val = 1;
65+
for (char c : str) {
66+
hash_val *= hash.at(c);
67+
}
68+
69+
return hash_val;
70+
}
71+
72+
// This funtion calculates the hash of string
73+
long long anagram_count(const std::string& parent, const std::string& child) {
74+
long long hash_child = get_hash(child);
75+
76+
// to keep count of all anagrams
77+
long long count = 0;
78+
79+
// get the hash of first n characters where n is length of child
80+
long long hash_val = get_hash(parent.substr(0, child.size()));
81+
if (hash_val == hash_child) {
82+
count++;
83+
}
84+
85+
// As we are moving ahead one char at a time, to calculate the hash_val of next string
86+
// we can divide the last hash_val by the hash of char which is moving out
87+
// and multiply by the hash of char being moving in
88+
// e.g. in abcd, if hash_val of "abc" is n, then hash_val of "bcd" is: n / hash.at('a') * hash.at('d');
89+
for (size_t index = child.size(); index < parent.size(); ++index) {
90+
hash_val /= hash.at(parent[index - child.size()]);
91+
hash_val *= hash.at(parent[index]);
92+
if (hash_val == hash_child) {
93+
count++;
94+
}
95+
}
96+
97+
return count;
98+
}
99+
100+
int main() {
101+
std::cout << anagram_count("forbtorfxdofrm", "for") << std::endl; // 3
102+
std::cout << anagram_count("aabaabaa", "aaba") << std::endl; // 4
103+
std::cout << anagram_count("AdnBndAndBdaBn", "dAn") << std::endl; // 4
104+
std::cout << anagram_count("AbrAcadAbRa", "cAda") << std::endl; // 2
105+
return 0;
106+
}

0 commit comments

Comments
 (0)