统计大量文本中重复字符串的最大个数

有大量中文繁体的文本,都是网上摘取的,大小有6G。需要提取文本中相同的字符串的最大个数

有几个关键问题:

1.字符串的粒度如何确定?如何表示字符串的唯一位置索引?

2.字符串过多,如何快速确定是否相同,时间复杂度要尽量低

3.文本过多,无法放入内存怎么办

4.如何统计相同hash值的个数,以及记录它们的索引位置

对于1,每次读取一行,然后以100个字节为一组作为比较的字符串。每行最后一组,以实际读取到的字符串大小为准;将行号和所在组号作为二元组,唯一标识字符串hash值位置索引

对于2,必须hash了。但是冲突如何解决?网上有很多字符串hash算法,冲突率比较低。本人用二次hash来尽量避免冲突,就算有个别误差,也可以接受

对于3,由于最终比较的是hash值,将它们再次hash到10个小文件中,这样保证同一个hash值在同一个文件中。然后分别统计每个小文件中最大的重复度,最后取最大值输出即可。

对于4,用STL中的map,将两个hash值作为map的key,而vector<索引>作为map的value值,即map<HashKey_S, vector<PositionOfText_S>, Classcomp_S>,对于key还要定义小于号操作符Classcomp_S

  1. //map中key大小比较函数对象  
  2. struct Classcomp_S {  
  3.     bool operator() (const HashKey_S &lkey, const HashKey_S &rkey) const  
  4.     {  
  5.         bool flag = false;  
  6.         if (lkey.uifirsthash < rkey.uifirsthash)  
  7.             flag = true;  
  8.         else if(lkey.uifirsthash == rkey.uifirsthash)  
  9.         {  
  10.             if (lkey.uisecondhash < rkey.uisecondhash)  
  11.                 flag = true;  
  12.         }  
  13.         return flag;  
  14.     }  
  15. };  



写代码中发现,有些字符串重复度很高,它们是一些不可打印的相同字符或者几乎相同的字符。最后用函数countDiffChar统计不同字符个数,将比较小的过滤掉。

代码写的比较乱,"../../data/filelist.txt"是6G原始文本的文件名列表,"../../data/hash2line.txt"是提取hash值和位置索引后存储的文件,之后还要将它切分。

代码如下:

main.cpp

  1. #include <iostream>  
  2. #include "statSameLine.h"  
  3. using namespace std;  
  4.   
  5. int main()  
  6. {  
  7.     MakeResult();  
  8.     return 0;  
  9. }  


statSameLine.h

  1. #ifndef STATSAMELINE_H  
  2. #define STATSAMELINE_H  
  3.   
  4. typedef unsigned char BYTE;  
  5. typedef unsigned int DWORD;  
  6. typedef unsigned short WORD;  
  7.   
  8.   
  9. struct HashKey_S  
  10. {  
  11.     HashKey_S(DWORD uiFirst = 0, DWORD uiSecond = 0):uifirsthash(uiFirst), uisecondhash(uiSecond){  
  12.     }  
  13.     HashKey_S(const HashKey_S &stHash):uifirsthash(stHash.uifirsthash), uisecondhash(stHash.uisecondhash){  
  14.     }  
  15.     DWORD uifirsthash;  
  16.     DWORD uisecondhash;  
  17. };  
  18.   
  19. struct PositionOfText_S  
  20. {  
  21.     PositionOfText_S(DWORD uiFile = 0, DWORD uiLine = 0, DWORD uiBatch = 0):uiFileNum(uiFile), uiLineNum(uiLine), uiBatch(uiBatch){  
  22.   
  23.     }  
  24.   
  25.     PositionOfText_S(const PositionOfText_S &pos):uiFileNum(pos.uiFileNum), uiLineNum(pos.uiLineNum), uiBatch(pos.uiBatch)  
  26.     {  
  27.   
  28.     }  
  29.   
  30.     DWORD uiFileNum;  
  31.     DWORD uiLineNum;  
  32.     DWORD uiBatch;  
  33. };  
  34.   
  35. struct Hash2LineTable_S  
  36. {  
  37.     DWORD uiFileNum;  
  38.     DWORD uiLineNum;  
  39.     DWORD uiBatch;  
  40.     HashKey_S sthashkey;  
  41. };  
  42.   
  43.   
  44. void TestStl();  
  45. void MakeResult();  
  46.   
  47.   
  48.   
  49. #endif // STATSAMELINE_H  


statSameLine.cpp
  1. #include "statSameLine.h"  
  2.   
  3. #include <cstring>  
  4. #include <cassert>  
  5. #include <cstdlib>  
  6. #include <cstdio>  
  7.   
  8. #include <iostream>  
  9. #include <fstream>  
  10. #include <vector>  
  11. #include <string>  
  12. #include <map>  
  13. #include <algorithm>  
  14. #include <iomanip>  
  15. #include <locale>  
  16. #include <tchar.h>  
  17.   
  18. #include "hash.h"  
  19.   
  20. using namespace std;  
  21. //map中key大小比较函数对象  
  22. struct Classcomp_S {  
  23.     bool operator() (const HashKey_S &lkey, const HashKey_S &rkey) const  
  24.     {  
  25.         bool flag = false;  
  26.         if (lkey.uifirsthash < rkey.uifirsthash)  
  27.             flag = true;  
  28.         else if(lkey.uifirsthash == rkey.uifirsthash)  
  29.         {  
  30.             if (lkey.uisecondhash < rkey.uisecondhash)  
  31.                 flag = true;  
  32.         }  
  33.         return flag;  
  34.     }  
  35. };  
  36. //去除字符串头尾空格与tab  
  37. string trimEnd(string &str)  
  38. {  
  39.     const string delim =" \t\r" ;  
  40.     string r=str.erase(str.find_last_not_of(delim)+1);  
  41.     return r.erase(0,r.find_first_not_of(delim));  
  42. }  
  43. //统计字符串中不同字符的个数,目的是为了去掉那些大量无意义的相同字符  
  44. int countDiffChar(string &stext)  
  45. {  
  46.     const int isize = 256;  
  47.     int bitarr[isize] = {0};  
  48.     for (size_t i = 0; i < stext.size(); ++i)  
  49.     {  
  50.         int iindex = (int)stext[i];  
  51.         bitarr[iindex] = 1;  
  52.     }  
  53.   
  54.     int icount = 0;  
  55.     for (int i = 0; i < isize; ++i)  
  56.     {  
  57.         if (bitarr[i] != 0)  
  58.             ++icount;  
  59.     }  
  60.     return icount;  
  61.   
  62. }  
  63. //存储一行文本,将6G文件的hash值以及每段文本所在位置保存,便于第二次处理  
  64. void storeOneLine(ofstream &ofs, const string &sLine, DWORD uiFileNum, DWORD uiLineNum, int &iFilterNumber)  
  65. {  
  66.       
  67.     const int iLengthOfBatch = 100;  
  68.   
  69.     int iAllBatches, iLineSize;  
  70.   
  71.   
  72.     DWORD uiHashcode;  
  73.   
  74.     char szBatchLine[iLengthOfBatch + 1];  
  75.   
  76.     Hash2LineTable_S stHash2LineTable;  
  77.   
  78.     iLineSize = sLine.size();  
  79.     iAllBatches = iLineSize / iLengthOfBatch + 1;  
  80.   
  81.     int iHashNum = 0;  
  82.       
  83.   
  84.     for (int i = 0; i < iAllBatches; ++i)  
  85.     {  
  86.         int iBegin, iEnd, iLength = iLengthOfBatch;  
  87.   
  88.         iBegin = i * iLengthOfBatch;  
  89.         iEnd = iBegin + iLengthOfBatch;  
  90.         //  
  91.         if (iBegin >= iLineSize)  
  92.             break;  
  93.         if (iEnd > iLineSize)  
  94.             iLength = iLineSize - iBegin;  
  95.   
  96.         memset(&stHash2LineTable, 0, sizeof(Hash2LineTable_S));  
  97.         memset(szBatchLine, 0, sizeof(szBatchLine));  
  98.   
  99.         //here is tangle, .................  
  100.         string sSubLine;  
  101.   
  102.         sSubLine = sLine.substr(iBegin, iLength);  
  103.         sSubLine = trimEnd(sSubLine);  
  104.         size_t uiLenOfSubstr = sSubLine.size();  
  105.         //cout << "uilen is " << uiLenOfSubstr << endl;  
  106.         if (uiLenOfSubstr < 50)  
  107.         {  
  108.             continue;  
  109.         }  
  110.         if (countDiffChar(sSubLine) < 3)  
  111.         {  
  112.             ++iFilterNumber;  
  113.             continue;  
  114.         }  
  115.   
  116.         sprintf(szBatchLine, "%s", sSubLine.c_str());  
  117.   
  118.         uiHashcode = BKDRHash(szBatchLine);  
  119.         stHash2LineTable.sthashkey.uifirsthash = uiHashcode;  
  120.         uiHashcode = APHash(szBatchLine);  
  121.         stHash2LineTable.sthashkey.uisecondhash = uiHashcode;  
  122.         stHash2LineTable.uiFileNum = uiFileNum;  
  123.         stHash2LineTable.uiLineNum = uiLineNum;  
  124.           
  125.         stHash2LineTable.uiBatch = i;  
  126.         //wirte one Hash2LineTable_S to file  
  127.         ofs.write((const char*)(&stHash2LineTable), sizeof(Hash2LineTable_S));  
  128.     }  
  129. }  
  130. //根据行号以及所在组,输出对应文本  
  131. void outputSpecifyFile(ofstream &ofs, const string &sfilename, DWORD uiLine, DWORD uiBatch)  
  132. {  
  133.   
  134.     const int iLengthOfBatch = 100;  
  135.   
  136.     ifstream ifs;  
  137.     ifs.open((sfilename.c_str()), ios::in);  
  138.     assert(ifs.is_open());  
  139.     string sLine, stHash2LineTable;  
  140.   
  141.     DWORD uiLineNum = 0;  
  142.     while (getline(ifs, sLine))  
  143.     {  
  144.         ++uiLineNum;  
  145.         if (uiLineNum == uiLine)  
  146.             break;  
  147.         sLine.clear();  
  148.     }  
  149.     ifs.close();  
  150.   
  151.     int iLineSize, iBegin, iEnd, iLength = iLengthOfBatch;  
  152.     iLineSize = sLine.size();  
  153.   
  154.     iBegin = uiBatch * iLengthOfBatch;  
  155.     iEnd = iBegin + iLengthOfBatch;  
  156.     //  
  157.     if (iBegin >= iLineSize)  
  158.     {  
  159.         cout << "error" << endl;  
  160.         return;  
  161.     }  
  162.   
  163.     if (iEnd > iLineSize)  
  164.         iLength = iLineSize - iBegin;  
  165.   
  166.   
  167.     stHash2LineTable = sLine.substr(iBegin, iLength);  
  168.     stHash2LineTable = trimEnd(stHash2LineTable);  
  169.     if (stHash2LineTable.size() < 50)  
  170.     {  
  171.         cout << "stHash2LineTable.size() < 50, error" << endl;  
  172.         return;  
  173.     }  
  174.     /*cout << "the size of substring is " << stHash2LineTable.size() << "-->"; 
  175.  
  176.     cout << "***************start\n";*/  
  177.     ofs.write((const char*)(stHash2LineTable.c_str()), stHash2LineTable.size());  
  178.     ofs << endl;  
  179.       
  180. }  
  181.   
  182. void parse_one_file(const char *pconefile, ofstream &ofs,  
  183.                    vector<DWORD> &vecline, DWORD uiFileNum, int &iFilterNumber)  
  184. {  
  185.     cout << "parse_one_file:" << pconefile << endl;  
  186.     int imaxbytes_line = 0;  
  187.   
  188.     DWORD uiLineNum = 0;  
  189.   
  190.     ifstream ifs;  
  191.     ifs.open((pconefile), ios::in);  
  192.     assert(ifs.is_open());  
  193.     //store every line of char  
  194.     string sLine;  
  195.   
  196.     //ofstream ofsUtf8;  
  197.     //ofsUtf8.open("utf8_chinese.txt", ios::binary );  
  198.   
  199.     while (getline(ifs, sLine))  
  200.     {  
  201.         ++uiLineNum;  
  202.         //erase some chars: \r, \t, \s  
  203.         sLine = trimEnd(sLine);  
  204.         int iLineSize = sLine.size();  
  205.         if (iLineSize == 0)  
  206.         {  
  207.             continue;  
  208.         }  
  209.         if (iLineSize > imaxbytes_line)  
  210.         {  
  211.             imaxbytes_line = iLineSize;  
  212.         }  
  213.         storeOneLine(ofs, sLine, uiFileNum, uiLineNum, iFilterNumber);  
  214.         /*ofsUtf8.write((char*)(sLine.c_str()), sLine.size()); 
  215.         ofsUtf8 << endl; 
  216.         if (uiLineNum > 100) 
  217.         { 
  218.              
  219.             break; 
  220.         }*/  
  221.         sLine.clear();  
  222.           
  223.   
  224.     }  
  225.     //ofsUtf8.close();  
  226.     ifs.close();  
  227.   
  228.     //uiLineNum from 1 to end  
  229.     vecline.push_back(uiLineNum);  
  230.     cout << imaxbytes_line << " is max bytes of every line" << endl;  
  231. }  
  232. //解析原始文本,存储每个字符串对应的hash值以及索引位置  
  233. int parse_all_file(const char *pcallfile, const char *pcwritefile)  
  234. {  
  235.     vector<DWORD> vecline;  
  236.     char cread;  
  237.     ifstream ifs;  
  238.     ofstream ofs;  
  239.   
  240.     int iFilterNumber = 0;  
  241.   
  242.     ofs.open(pcwritefile, ios::out | ios::binary);  
  243.     assert(ofs.is_open());  
  244.     ifs.open(pcallfile, ios::in);  
  245.     assert(ifs.is_open());  
  246.     string sLine;  
  247.     DWORD uiFileNum = 0;  
  248.     while (ifs.read(&cread, 1))  
  249.     {  
  250.         if (cread != 0x0a)  
  251.         {  
  252.             sLine.push_back(cread);  
  253.             continue;  
  254.         }  
  255.         ++uiFileNum;  
  256.   
  257.         sLine = string("../../../data/alldata/") + sLine;  
  258.         parse_one_file(sLine.c_str(), ofs, vecline, uiFileNum, iFilterNumber);  
  259.         sLine.clear();  
  260.     }  
  261.     ofs.close();  
  262.     ifs.close();  
  263.     ofs.open("../../../data/linenum.txt");  
  264.   
  265.     for (size_t i = 0; i < vecline.size(); ++i)  
  266.     {  
  267.         ofs << vecline[i] << endl;  
  268.         cout << vecline[i] << endl;  
  269.     }  
  270.     ofs.close();  
  271.   
  272.     return iFilterNumber;  
  273.   
  274. }  
  275. //切分文件,便于直接在内存中建立map  
  276. void splitfile(const char *pcfile)  
  277. {  
  278.     ifstream ifs;  
  279.     ifs.open(pcfile, ios::in | ios::binary);  
  280.     assert(ifs.is_open());  
  281.   
  282.     Hash2LineTable_S stHash2LineTable;  
  283.     DWORD uifirsthashcode;  
  284.   
  285.     char szcbuffer[150], swritename[80];  
  286.     int inum = 0;  
  287.     const int ifilenum = 10;  
  288.   
  289.     ofstream szofs[ifilenum];  
  290.     for(int i = 0; i < ifilenum; ++i)  
  291.     {  
  292.         sprintf (swritename, "../../../data/hash_%d.txt", i);  
  293.         szofs[i].open(swritename, ios::out | ios::binary);  
  294.   
  295.         memset(swritename, 0, sizeof(swritename));  
  296.     }  
  297.   
  298.     while(ifs.read((char*)(&stHash2LineTable), sizeof(Hash2LineTable_S)))  
  299.     {  
  300.         uifirsthashcode = stHash2LineTable.sthashkey.uifirsthash;  
  301.   
  302.         DWORD uihashvalue;  
  303.         sprintf(szcbuffer, "%d", uifirsthashcode);  
  304.   
  305.         uihashvalue = ELFHash(szcbuffer) % ifilenum;  
  306.   
  307.         if (uihashvalue == 1)  
  308.             ++inum;  
  309.   
  310.         szofs[uihashvalue].write((char*)(&stHash2LineTable), sizeof(Hash2LineTable_S));  
  311.   
  312.         memset(&stHash2LineTable, 0, sizeof(Hash2LineTable_S));  
  313.         memset(swritename, 0, sizeof(swritename));  
  314.   
  315.     }  
  316.     ifs.close();  
  317.     cout << "splitfile hash value 1, num is " << inum << endl;  
  318.   
  319.     for (int i = 0; i < ifilenum; ++i)  
  320.     {  
  321.         szofs[i].close();  
  322.     }  
  323. }  
  324.   
  325.   
  326.   
  327. void getVecLine(vector<DWORD> &vecline)  
  328. {  
  329.     ifstream ifs;  
  330.     ifs.open("../../../data/linenum.txt", ios::out);  
  331.     assert(ifs.is_open());  
  332.     DWORD uiread;  
  333.     string sLine;  
  334.     vecline.clear();  
  335.     while (getline(ifs, sLine))  
  336.     {  
  337.         uiread = atoi(sLine.c_str());  
  338.         vecline.push_back(uiread);  
  339.     };  
  340.     ifs.close();  
  341. }  
  342.   
  343.   
  344. vector<PositionOfText_S> getSameLineOfCount(const char *pcfile, DWORD &uiDegreeOfDup, vector<PositionOfText_S> &stMaxPos)  
  345. {  
  346.     cout << "getSameLineOfCount, file name is " << pcfile << endl;  
  347.     vector<PositionOfText_S> *pmaxlineOfPos;  
  348.     ifstream ifs;  
  349.     ifs.open(pcfile, ios::in | ios::binary);  
  350.     assert(ifs.is_open());  
  351.   
  352.     Hash2LineTable_S stHash2LineTable;  
  353.     memset(&stHash2LineTable, 0, sizeof(Hash2LineTable_S));  
  354.   
  355.   
  356.     map<HashKey_S, vector<PositionOfText_S>, Classcomp_S> maphash2postion;  
  357.     long lkeynum = 0;  
  358.   
  359.     while (ifs.eof() == false)  
  360.     {  
  361.         //cout << ifs.tellg() << endl;  
  362.         ifs.read((char*)(&stHash2LineTable), sizeof(Hash2LineTable_S));  
  363.         ++lkeynum;  
  364.         DWORD uiFileNum, uiLine, uiBatch;  
  365.         uiFileNum = stHash2LineTable.uiFileNum;  
  366.         uiLine = stHash2LineTable.uiLineNum;  
  367.         if (uiLine > 498417)  
  368.         {  
  369.             cout << "uilinenum is large than 498417, its value is " << uiLine << endl;  
  370.             break;  
  371.         }  
  372.         uiBatch = stHash2LineTable.uiBatch;  
  373.         maphash2postion[stHash2LineTable.sthashkey].push_back(PositionOfText_S(uiFileNum, uiLine, uiBatch));  
  374.     }  
  375.     cout << "*************map size************\n";  
  376. //    cout << "the num of key value is " << lkeynum << endl;  
  377.     cout << "the num of map is " << maphash2postion.size() << endl;  
  378.   
  379.     ifs.close();  
  380.     DWORD uimaxcount = 0;  
  381.   
  382.     const HashKey_S *pmaxkey = NULL;  
  383.     vector<PositionOfText_S> *pvecposOfText = NULL;  
  384.     ofstream ofs;  
  385.     ofs.open("../../../data/hash2linetable.txt");  
  386.     /*保存每个字符串重复度,hashkey,以及位置(虽然本程序用不到) 
  387.      * 
  388.      *file format 
  389.      *1.uicount, the max count of same line, the size of vector<PositionOfText_S> 
  390.      *2.HashKey_S 
  391.      *3.many PositionOfText_S, the num is uicount 
  392.      */  
  393.     for (map<HashKey_S, vector<PositionOfText_S>, Classcomp_S >::iterator it = maphash2postion.begin(); it != maphash2postion.end(); ++it)  
  394.     {  
  395.         DWORD uicount;  
  396.         const HashKey_S *pkey = &(it->first);  
  397.         pvecposOfText = &(it->second);  
  398.         uicount = pvecposOfText->size();  
  399.         if (uicount > uimaxcount)  
  400.         {  
  401.             uimaxcount = uicount;  
  402.             pmaxlineOfPos = pvecposOfText;  
  403.             pmaxkey = pkey;  
  404.         }  
  405.           
  406.         ofs.write((char*)(&uicount), sizeof(DWORD));  
  407.         ofs.write((char*)(pkey), sizeof(HashKey_S));  
  408.         for (size_t i = 0; i < uicount; ++i)  
  409.             ofs.write((char*)(&(pvecposOfText->at(i))), sizeof(PositionOfText_S));  
  410.     }  
  411.     ofs.close();  
  412.     cout << "maxcount is " << uimaxcount << endl;  
  413. //    cout << "maxline is " << uimaxline << endl;  
  414.   //  cout << "max key, first is " << pmaxkey->uifirsthash << ", second is " << pmaxkey->uisecondhash << endl;  
  415.     if (uimaxcount > uiDegreeOfDup)  
  416.     {  
  417.         uiDegreeOfDup = uimaxcount;  
  418.         stMaxPos = *pmaxlineOfPos;  
  419.     }  
  420.   
  421.     return *pmaxlineOfPos;  
  422.   
  423. }  
  424.   
  425. void print_one_max_line(ofstream &ofs, const char *pcFileList, const PositionOfText_S &stPos, int *pibit)  
  426. {  
  427.     DWORD uiLine, uiFileNum;  
  428.     uiFileNum = stPos.uiFileNum;      
  429.     uiLine = stPos.uiLineNum;  
  430.   
  431.     ifstream ifs;  
  432.     ifs.open(pcFileList, ios::in);  
  433.     assert(ifs.is_open());  
  434.     string sLine;  
  435.   
  436.     int inum = 0;  
  437.     while (getline(ifs, sLine))  
  438.     {  
  439.         ++inum;  
  440.         if (inum == uiFileNum)  
  441.         {  
  442.             ofs << sLine << ":the num of line is " << uiLine << ", batch is " << stPos.uiBatch << endl;  
  443.   
  444.             sLine = string("../../../data/alldata/") + sLine;  
  445.             outputSpecifyFile(ofs, sLine, uiLine, stPos.uiBatch);  
  446.             break;  
  447.         }  
  448.         sLine.clear();  
  449.     }  
  450.     ifs.close();  
  451. }  
  452.   
  453. void output_result(const char *pcFileList, vector<PositionOfText_S> *pmaxlineOfPos, const char *pcName)  
  454. {  
  455.     cout << "output_result to file:" << pcName << endl;  
  456.     int isum = 0;  
  457.     ofstream ofs;  
  458.     ofs.open(pcName, ios::out | ios::binary);  
  459.     int szBit[30];  
  460.     for (vector<PositionOfText_S>::const_iterator cit = pmaxlineOfPos->begin(); cit != pmaxlineOfPos->end(); ++cit)  
  461.     {  
  462.         /*if (isum++ == 20) 
  463.         { 
  464.             break; 
  465.         }*/  
  466.         print_one_max_line(ofs, pcFileList, *cit, szBit);  
  467.     }  
  468.     ofs.close();  
  469. }  
  470.   
  471. void MakeResult()  
  472. {  
  473.     const char *pcWriteName = "../../../data/hash2line.txt", *pcFileList = "../../../data/filelist.txt";  
  474.     const int ifilenum = 10;  
  475.   
  476.     char szName[80];  
  477.     int iFilterNumber = 0;  
  478.     //解析所有文件  
  479.     //iFilterNumber = parse_all_file(pcFileList, pcWriteName);  
  480.     //将大文件划分为10个小文件  
  481.     //splitfile(pcWriteName);  
  482.   
  483.     DWORD uiDegreeOfDup = 0;  
  484.     vector<PositionOfText_S> stPos, stMaxPos;  
  485.     for (int i = 0; i < ifilenum; ++i)  
  486.     {  
  487.         cout << "***every file, the pos of max line***\n";  
  488.         memset(szName, 0, sizeof(szName));  
  489.         sprintf(szName, "../../../data/hash_%d.txt", i);  
  490.         //获取每个小文件的最大重复子串  
  491.         stPos = getSameLineOfCount(szName, uiDegreeOfDup, stMaxPos);  
  492.   
  493.         memset(szName, 0, sizeof(szName));  
  494.         sprintf(szName, "../../../data/hash_%d_maxpostext.txt", i);  
  495.         output_result(pcFileList, &stPos, szName);  
  496.         stPos.clear();  
  497.     }  
  498.     const char *pcOutFileName = "degree_of_dup_result.txt";  
  499.     //output_result(pcFileList, &stMaxPos, pcOutFileName);  
  500.     ofstream ofs;  
  501.     ofs.open(pcOutFileName, ios::out | ios::app);  
  502.     ofs << "**************" << endl;  
  503.     ofs << "uiDegreeOfDup is " << uiDegreeOfDup << endl;  
  504.     ofs << "filter num is " << iFilterNumber << endl;  
  505.     ofs.close();  
  506.   
  507. }  


hash.h
  1. #ifndef HASH_H  
  2. #define HASH_H  
  3. typedef unsigned char BYTE;  
  4. typedef unsigned int DWORD;  
  5.   
  6. DWORD SDBMHash(char *pcstr);  
  7.   
  8. // RS Hash Function  
  9. DWORD RSHash(char *pcstr);  
  10. // JS Hash Function  
  11. DWORD JSHash(char *pcstr);  
  12.   
  13. // P. J. Weinberger Hash Function  
  14. DWORD PJWHash(char *pcstr);  
  15.   
  16. // ELF Hash Function  
  17. DWORD ELFHash(char *pstr);  
  18.   
  19. // BKDR Hash Function  
  20. DWORD BKDRHash(char *pcstr);  
  21. // DJB Hash Function  
  22. DWORD DJBHash(char *pcstr);  
  23. // AP Hash Function  
  24. DWORD APHash(char *pcstr);  
  25. #endif // HASH_H  

hash.cpp


  1. #include "hash.h"  
  2.   
  3. DWORD SDBMHash(char *pcstr)  
  4. {  
  5.     if (*pcstr == 0)  
  6.         return 0;  
  7.     DWORD hash = 0;  
  8.   
  9.     while (*pcstr)  
  10.     {  
  11.         // equivalent to: hash = 65599*hash + (*pcstr++);  
  12.         hash = (*pcstr++) + (hash << 6) + (hash << 16) - hash;  
  13.     }  
  14.   
  15.     return (hash & 0x7FFFFFFF);  
  16. }  
  17.   
  18. // RS Hash Function  
  19. DWORD RSHash(char *pcstr)  
  20. {  
  21.     if (*pcstr == 0)  
  22.         return 0;  
  23.     DWORD b = 378551;  
  24.     DWORD a = 63689;  
  25.     DWORD hash = 0;  
  26.   
  27.     while (*pcstr)  
  28.     {  
  29.         hash = hash * a + (*pcstr++);  
  30.         a *= b;  
  31.     }  
  32.   
  33.     return (hash & 0x7FFFFFFF);  
  34. }  
  35.   
  36. // JS Hash Function  
  37. DWORD JSHash(char *pcstr)  
  38. {  
  39.     if (*pcstr == 0)  
  40.         return 0;  
  41.     DWORD hash = 1315423911;  
  42.   
  43.     while (*pcstr)  
  44.     {  
  45.         hash ^= ((hash << 5) + (*pcstr++) + (hash >> 2));  
  46.     }  
  47.   
  48.     return (hash & 0x7FFFFFFF);  
  49. }  
  50.   
  51. // P. J. Weinberger Hash Function  
  52. DWORD PJWHash(char *pcstr)  
  53. {  
  54.     if (*pcstr == 0)  
  55.         return 0;  
  56.     DWORD BitsInUnignedInt = (DWORD)(sizeof(DWORD) * 8);  
  57.     DWORD ThreeQuarters    = (DWORD)((BitsInUnignedInt  * 3) / 4);  
  58.     DWORD OneEighth        = (DWORD)(BitsInUnignedInt / 8);  
  59.     DWORD HighBits         = (DWORD)(0xFFFFFFFF) << (BitsInUnignedInt - OneEighth);  
  60.     DWORD hash             = 0;  
  61.     DWORD test             = 0;  
  62.   
  63.     while (*pcstr)  
  64.     {  
  65.         hash = (hash << OneEighth) + (*pcstr++);  
  66.         if ((test = hash & HighBits) != 0)  
  67.         {  
  68.             hash = ((hash ^ (test >> ThreeQuarters)) & (~HighBits));  
  69.         }  
  70.     }  
  71.   
  72.     return (hash & 0x7FFFFFFF);  
  73. }  
  74.   
  75. // ELF Hash Function  
  76. DWORD ELFHash(char *pcstr)  
  77. {  
  78.     if (*pcstr == 0)  
  79.         return 0;  
  80.     DWORD hash = 0;  
  81.     DWORD x    = 0;  
  82.   
  83.     while (*pcstr)  
  84.     {  
  85.         hash = (hash << 4) + (*pcstr++);  
  86.         if ((x = hash & 0xF0000000L) != 0)  
  87.         {  
  88.             hash ^= (x >> 24);  
  89.             hash &= ~x;  
  90.         }  
  91.     }  
  92.   
  93.     return (hash & 0x7FFFFFFF);  
  94. }  
  95.   
  96. // BKDR Hash Function  
  97. DWORD BKDRHash(char *pcstr)  
  98. {  
  99.     if (*pcstr == 0)  
  100.         return 0;  
  101.     DWORD seed = 131; // 31 131 1313 13131 131313 etc..  
  102.     DWORD hash = 0;  
  103.   
  104.     while (*pcstr)  
  105.     {  
  106.         hash = hash * seed + (*pcstr++);  
  107.     }  
  108.   
  109.     return (hash & 0x7FFFFFFF);  
  110. }  
  111.   
  112. // DJB Hash Function  
  113. DWORD DJBHash(char *pcstr)  
  114. {  
  115.     if (*pcstr == 0)  
  116.         return 0;  
  117.     DWORD hash = 5381;  
  118.   
  119.     while (*pcstr)  
  120.     {  
  121.         hash += (hash << 5) + (*pcstr++);  
  122.     }  
  123.   
  124.     return (hash & 0x7FFFFFFF);  
  125. }  
  126.   
  127. // AP Hash Function  
  128. DWORD APHash(char *pcstr)  
  129. {  
  130.     if (*pcstr == 0)  
  131.         return 0;  
  132.     DWORD hash = 0;  
  133.     int i;  
  134.   
  135.     for (i=0; *pcstr; i++)  
  136.     {  
  137.         if ((i & 1) == 0)  
  138.         {  
  139.             hash ^= ((hash << 7) ^ (*pcstr++) ^ (hash >> 3));  
  140.         }  
  141.         else  
  142.         {  
  143.             hash ^= (~((hash << 11) ^ (*pcstr++) ^ (hash >> 5)));  
  144.         }  
  145.     }  
  146.   
  147.     return (hash & 0x7FFFFFFF);  
  148. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值