Advertisement
Guest User

anagram test

a guest
Aug 9th, 2013
502
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.21 KB | None | 0 0
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <map>
  4. #include <cctype>
  5. #include <string>
  6. #include <algorithm>
  7. #include <limits>
  8.  
  9. #include <iostream>
  10. #include <iterator>
  11.  
  12. using namespace std;
  13.  
  14. typedef unsigned long long hash_t;
  15.  
  16. class mystring : public std::string {
  17.     public: hash_t hash;
  18.     void rehash(void)
  19.     {
  20.         static const unsigned short primetable[256] = {/*{{{*/
  21.             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,
  22.             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,
  23.             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,
  24.             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,
  25.             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,
  26.             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,
  27.             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,
  28.             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
  29.         /*}}}*/};
  30.         hash_t prod = 1;
  31.         bool overflow = false;
  32.  
  33.         for (size_t i = 0; i < length(); i++)
  34.         {
  35.             unsigned short p = primetable[(unsigned char)tolower(c_str()[i])];
  36.             overflow |= (prod > (hash_t)-1 / p);
  37.             prod *= p;
  38.         }
  39.         if (overflow)
  40.             prod ^= 1;
  41.         hash = prod;
  42.     }
  43. };
  44.  
  45.  
  46. bool is_anagram(const mystring & s1, const mystring & s2)
  47. {
  48.     auto check = [](const std::string& x)
  49.     {
  50.         std::map<char, unsigned> counter;
  51.         for(auto c : x)
  52.         {
  53.             auto it = counter.find(c);
  54.             if(it == counter.end())
  55.                 counter[c] = 1;
  56.             else
  57.                 ++counter[c];
  58.         }
  59.         return counter;
  60.     };
  61.  
  62.     return check(s1) == check(s2);
  63. }
  64.  
  65.  
  66. bool is_anagram1(const mystring & s1, const mystring & s2)
  67. {
  68.     auto check = [](const mystring& x)
  69.     {
  70.         std::map<char, unsigned> counter;
  71.         for(auto c : x)
  72.         {
  73.         ++counter[c];
  74.         }
  75.         return counter;
  76.     };
  77.  
  78.     return check(s1) == check(s2);
  79. }
  80.  
  81.  
  82. bool is_anagram2(mystring s1, mystring s2)
  83. {
  84.     std::sort(s1.begin(), s1.end());
  85.     std::sort(s2.begin(), s2.end());
  86.     return s1 == s2;
  87. }
  88.  
  89.  
  90. bool is_anagram3(mystring s1, mystring s2)
  91. {
  92.     if (s1.length() != s2.length()) return false;
  93.     std::sort(s1.begin(), s1.end());
  94.     std::sort(s2.begin(), s2.end());
  95.     return s1 == s2;
  96. }
  97.  
  98. bool is_anagram4(const mystring &s1, const mystring &s2)
  99. {
  100.     if (s1.length() != s2.length()) return false;
  101.     {
  102.         int arr[256] = {};
  103.         for(mystring::size_type i = 0; i < s1.length(); i++)
  104.         {
  105.         arr[(unsigned)s1[i]]++;
  106.         arr[(unsigned)s2[i]]--;
  107.         }
  108.         for(auto i : arr)
  109.         {
  110.         if (i) return false;
  111.         }
  112.     }
  113.     return true;
  114. }
  115.  
  116. bool is_anagram5(const mystring &s1, const mystring &s2)
  117. {
  118.     if (s1.length() != s2.length()) return false;
  119.     {
  120.         int arr[26] = {};
  121.         for(mystring::size_type i = 0; i < s1.length(); i++)
  122.         {
  123.         arr[(unsigned)tolower(s1[i])-'a']++;
  124.         arr[(unsigned)tolower(s2[i])-'a']--;
  125.         }
  126.         for(auto i : arr)
  127.         {
  128.         if (i) return false;
  129.         }
  130.     }
  131.     return true;
  132. }
  133.  
  134. bool is_anagram6(const mystring &s1, const mystring &s2)
  135. {
  136.     if (s1.hash != s2.hash) return false;
  137.     if ((s1.hash & 1) != 0) return true;
  138.     cout << "x";
  139.     return is_anagram4(s1, s2);
  140. }
  141.  
  142. template<typename T>
  143. void bm(const char *name, T func,
  144.     const vector<mystring> &dict)
  145. {
  146.     double time = clock() / (double)CLOCKS_PER_SEC;
  147.     int hits = 0;
  148.     for (size_t i = 0; i < dict.size(); i++)
  149.         for (size_t j = i + 1; j < dict.size(); j++)
  150.             hits += func(dict[i], dict[j]) ? 1 : 0;
  151.     time = clock() / (double)CLOCKS_PER_SEC - time;
  152.     cout << "Function" << left << setw(15) << name
  153.      << " time: " << right << setw(8) << time
  154.      << "s hits: " << hits << endl;
  155. }
  156.  
  157.  
  158. #define BM(x) bm(#x, x, dict)
  159.  
  160. int main()
  161. {
  162.     cout << "loading.." << endl;
  163.     vector<mystring> dict((istream_iterator<mystring>(cin)), istream_iterator<mystring>());
  164.  
  165.     cout << "hashing.." << endl;
  166.     for (mystring &e: dict) e.rehash();
  167.  
  168.     cout << "profiling.." << endl;
  169.     BM(is_anagram);
  170.     BM(is_anagram1);
  171.     BM(is_anagram2);
  172.     BM(is_anagram3);
  173.     BM(is_anagram4);
  174.     BM(is_anagram5);
  175.     BM(is_anagram6);
  176.     return 0;
  177. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement