Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <iomanip>
- #include <map>
- #include <cctype>
- #include <string>
- #include <algorithm>
- #include <limits>
- #include <iostream>
- #include <iterator>
- using namespace std;
- typedef unsigned long long hash_t;
- class mystring : public std::string {
- public: hash_t hash;
- void rehash(void)
- {
- static const unsigned short primetable[256] = {/*{{{*/
- 1, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619,
- 821, 823, 827, 829, 839, 853, 857, 107, 859, 863, 877, 881, 883, 109, 887, 907, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 911, 919, 929, 937, 941, 947,
- 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811,
- 359, 11, 61, 31, 37, 3, 71, 43, 59, 7, 101, 79, 29, 53, 13, 23, 47, 103, 17, 5, 19, 41, 73, 83, 89, 67, 97, 367, 373, 379, 383, 389,
- 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427,
- 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171,
- 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599,
- 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353
- /*}}}*/};
- hash_t prod = 1;
- bool overflow = false;
- for (size_t i = 0; i < length(); i++)
- {
- unsigned short p = primetable[(unsigned char)tolower(c_str()[i])];
- overflow |= (prod > (hash_t)-1 / p);
- prod *= p;
- }
- if (overflow)
- prod ^= 1;
- hash = prod;
- }
- };
- bool is_anagram(const mystring & s1, const mystring & s2)
- {
- auto check = [](const std::string& x)
- {
- std::map<char, unsigned> counter;
- for(auto c : x)
- {
- auto it = counter.find(c);
- if(it == counter.end())
- counter[c] = 1;
- else
- ++counter[c];
- }
- return counter;
- };
- return check(s1) == check(s2);
- }
- bool is_anagram1(const mystring & s1, const mystring & s2)
- {
- auto check = [](const mystring& x)
- {
- std::map<char, unsigned> counter;
- for(auto c : x)
- {
- ++counter[c];
- }
- return counter;
- };
- return check(s1) == check(s2);
- }
- bool is_anagram2(mystring s1, mystring s2)
- {
- std::sort(s1.begin(), s1.end());
- std::sort(s2.begin(), s2.end());
- return s1 == s2;
- }
- bool is_anagram3(mystring s1, mystring s2)
- {
- if (s1.length() != s2.length()) return false;
- std::sort(s1.begin(), s1.end());
- std::sort(s2.begin(), s2.end());
- return s1 == s2;
- }
- bool is_anagram4(const mystring &s1, const mystring &s2)
- {
- if (s1.length() != s2.length()) return false;
- {
- int arr[256] = {};
- for(mystring::size_type i = 0; i < s1.length(); i++)
- {
- arr[(unsigned)s1[i]]++;
- arr[(unsigned)s2[i]]--;
- }
- for(auto i : arr)
- {
- if (i) return false;
- }
- }
- return true;
- }
- bool is_anagram5(const mystring &s1, const mystring &s2)
- {
- if (s1.length() != s2.length()) return false;
- {
- int arr[26] = {};
- for(mystring::size_type i = 0; i < s1.length(); i++)
- {
- arr[(unsigned)tolower(s1[i])-'a']++;
- arr[(unsigned)tolower(s2[i])-'a']--;
- }
- for(auto i : arr)
- {
- if (i) return false;
- }
- }
- return true;
- }
- bool is_anagram6(const mystring &s1, const mystring &s2)
- {
- if (s1.hash != s2.hash) return false;
- if ((s1.hash & 1) != 0) return true;
- cout << "x";
- return is_anagram4(s1, s2);
- }
- template<typename T>
- void bm(const char *name, T func,
- const vector<mystring> &dict)
- {
- double time = clock() / (double)CLOCKS_PER_SEC;
- int hits = 0;
- for (size_t i = 0; i < dict.size(); i++)
- for (size_t j = i + 1; j < dict.size(); j++)
- hits += func(dict[i], dict[j]) ? 1 : 0;
- time = clock() / (double)CLOCKS_PER_SEC - time;
- cout << "Function" << left << setw(15) << name
- << " time: " << right << setw(8) << time
- << "s hits: " << hits << endl;
- }
- #define BM(x) bm(#x, x, dict)
- int main()
- {
- cout << "loading.." << endl;
- vector<mystring> dict((istream_iterator<mystring>(cin)), istream_iterator<mystring>());
- cout << "hashing.." << endl;
- for (mystring &e: dict) e.rehash();
- cout << "profiling.." << endl;
- BM(is_anagram);
- BM(is_anagram1);
- BM(is_anagram2);
- BM(is_anagram3);
- BM(is_anagram4);
- BM(is_anagram5);
- BM(is_anagram6);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement