WordSegment.cpp
上传用户:mesing
上传日期:2022-05-05
资源大小:353k
文件大小:6k
源码类别:

多国语言处理

开发平台:

C/C++

  1. #include<iostream>
  2. #include<fstream>
  3. #include<vector>
  4. #include<string>
  5. #include<stack>
  6. using namespace std;
  7. const int s1 = 0XB0,s2 = 0XA1,e1 = 0XF8,e2 = 0XFF;
  8. const int maxwordlen = 50;
  9. struct Second
  10. {
  11. string key;
  12. Second *next;
  13. Second(string k = "",Second *n = 0):key(k),next(n){}
  14. };
  15. struct Head
  16. {
  17. int size;
  18. string key;
  19. vector<Second*> W;
  20. Head(string k = "",int s = 0):key(k),size(s){}
  21. };
  22. class Dictiory
  23. {
  24. vector<Head> H;
  25. ifstream fin;
  26. ifstream fcin;
  27. ofstream fout;
  28. int hash[e1 - s1][e2 - s2];
  29. int BinarySearch(string str,int k);
  30. int GetNum();
  31. void LoadDic();
  32. bool IsC(char c);
  33. bool IsEc(char c);
  34. void AddWord(string str,int k);
  35. void InsertWord(string str,int k);
  36. bool IsWord(string str,int k,int t);
  37. void SkipNotChinese(string &str,stack<string> &stk);
  38. public:
  39. Dictiory(string sfilename,string dfilename);
  40. void SegmentWord(string s);
  41. void PrintDic()
  42. {
  43. for(int i = 0; i < e1 - s1;i++)
  44. for(int j = 0; j < e2 - s2;j++)
  45. {
  46. if(hash[i][j] >= 0)
  47. {
  48. fout << H[hash[i][j]].key << endl;
  49. for(int k = 0; k < H[hash[i][j]].W.size() ;k++)
  50. {
  51. Second *t = H[hash[i][j]].W[k];
  52. while(t)
  53. {
  54. fout << H[hash[i][j]].key;
  55. fout << t->key << endl;
  56. t = t->next;
  57. }
  58. }
  59. }
  60. fout << endl;
  61. }
  62. }
  63. };
  64. Dictiory::Dictiory(string sfilename,string dfilename)
  65. {
  66. int i,j;
  67. for(i = 0; i < e1 - s1;i++)
  68. for(j = 0; j < e2 - s2;j++)
  69. hash[i][j] = -1;
  70. H.resize(6768);
  71. fin.open(sfilename.c_str());
  72. fout.open(dfilename.c_str());
  73. LoadDic();
  74. }
  75. int Dictiory::BinarySearch(string str,int k)
  76. {
  77. int len = str.length();
  78. int L = 0,R = H[k].W.size() - 1,M;
  79. while(L <= R)
  80. {
  81. M = (L + R)/2;
  82. if(H[k].W[M]->key.size() == len)
  83. return M;
  84. else if(H[k].W[M]->key.size() < len)
  85. L = M + 1;
  86. else R = M - 1;
  87. }
  88. return -1;
  89. }
  90. void Dictiory::AddWord(string str,int k)
  91. {
  92. if(str.length() > H[k].size)
  93. {
  94. H[k].size = str.length();
  95. Second *t = new Second(str);
  96. H[k].W.push_back(t);
  97. }
  98. else
  99. InsertWord(str,k);
  100. }
  101. void Dictiory::InsertWord(string str,int k)
  102. {
  103. int in = BinarySearch(str,k);
  104. if(in == -1)
  105. {
  106.    int L = 0,R = H[k].W.size() - 1;
  107.    int len = str.length();
  108.    while(L <= R&&len > H[k].W[L]->key.size())
  109. L++;
  110.    H[k].W.resize(H[k].W.size() + 1);
  111.    for(int i = R + 1;i > L;i--)
  112.   H[k].W[i] = H[k].W[i - 1];
  113.    Second *t = new Second(str);
  114.    H[k].W[L] = t;
  115. }
  116. else
  117. {
  118. Second *pre,*t = H[k].W[in];
  119. while(t)
  120. {
  121.   pre = t;
  122.   t = t->next;
  123. }
  124. pre->next = new Second(str);
  125. }
  126. }
  127. int Dictiory::GetNum()
  128. {
  129. char cstr[maxwordlen];
  130. fin.getline(cstr,maxwordlen);
  131. int n = 0,i;
  132. for(i = 0; i < strlen(cstr);i++)
  133. n = n * 10 + cstr[i] - '0';
  134. return n;
  135. }
  136. void Dictiory::LoadDic()
  137. {
  138. char cstr[maxwordlen];
  139. string str;
  140. int i,j,k = 0,wordnumber;
  141.     while(fin.getline(cstr,maxwordlen))
  142.     {
  143. i = (unsigned char)cstr[0] - s1;
  144. j = (unsigned char)cstr[1] - s2;
  145. hash[i][j] = k;
  146. H[k].key = cstr;
  147. wordnumber = GetNum();
  148. for(i = 0; i < wordnumber;i++)
  149. {
  150.              fin.getline(cstr,maxwordlen);             
  151.  str = cstr;
  152.  str = str.substr(2,str.length() - 2);  
  153.       AddWord(str,k);
  154. }
  155. k++;
  156. }
  157. }
  158. bool Dictiory::IsC(char c)
  159. {
  160. unsigned value =  unsigned((unsigned char)c);
  161. return value >= s1&&value < e1;
  162. }
  163. bool Dictiory::IsEc(char c)
  164. {
  165. unsigned value =  unsigned((unsigned char)c);
  166. return value <= 0X7F;
  167. }
  168. bool Dictiory::IsWord(string str,int k,int t)
  169. {
  170. Second *temp = H[k].W[t];
  171. while(temp)
  172. {
  173. if(temp->key == str)
  174. return true;
  175. temp = temp->next;
  176. }
  177. return false;
  178. }
  179. void Dictiory::SkipNotChinese(string &str,stack<string> &stk)
  180. {
  181. unsigned L = 0,R = str.length();
  182. while(L < R&&!IsC(str[L]))
  183. {
  184. if(!IsEc(str[L]))
  185. L++;
  186. L++;
  187. }
  188. if(L > 0)
  189. {
  190.     stk.push(str.substr(0,L));
  191.     str = str.substr(L,R - L);
  192. }
  193. }
  194. void Dictiory::SegmentWord(string s)
  195. {
  196. stack<string> stk;
  197. fcin.open(s.c_str());
  198. char cstr[maxwordlen];
  199. string str,sstr;
  200. int i,j,startpos,endpos;
  201. char c;
  202. while(fcin.read(&c,sizeof(char)))
  203. {
  204. if(!IsC(c))
  205. {
  206. if(!str.empty())
  207. {
  208. cout << str << " " << str.length() << endl;
  209.         startpos = 0,endpos = str.length();
  210.         while(startpos < endpos)
  211.         {
  212.        if(str.length() <= 2)
  213.        {
  214.        stk.push(str);
  215.        if(!sstr.empty())
  216.        {
  217.        str = sstr;
  218.        sstr.clear();
  219.         }
  220.         startpos += 2;
  221.         }
  222.        else
  223.        {
  224.        i = (unsigned char)str[0] - s1,j = (unsigned char)str[1] - s2;
  225.        if(hash[i][j] >= 0)
  226.        {
  227.         string word = str.substr(2,str.length() - 2);
  228.         int in = BinarySearch(word,hash[i][j]);
  229.         if((in != -1)&&IsWord(word,hash[i][j],in))
  230.         {
  231.         stk.push(H[hash[i][j]].key + word);
  232.         startpos += str.length();
  233.         str = sstr;
  234.         sstr.clear();
  235.          }
  236.          else
  237.          {
  238.          sstr = sstr + str.substr(0,2);
  239.          str = str.substr(2,str.length() - 2);
  240.          }
  241.          }
  242.          else
  243.          {
  244.           sstr = sstr + str.substr(0,2);
  245.           str = str.substr(2,str.length() - 2);
  246.           }
  247.          }
  248.          }
  249.          while(!stk.empty())
  250.                {
  251.             fout << stk.top() << endl;
  252.             stk.pop();
  253.               }
  254. }
  255. str.clear();
  256. str += c;
  257. while(fcin.read(&c,sizeof(char))&&!IsC(c))
  258.  str += c;
  259.  fout << str << endl;
  260.  cout << str << " " << str.length() <<  endl;
  261.  str.clear();
  262.  str += c;
  263.  fcin.read(&c,sizeof(char));
  264.  str += c;
  265. }
  266. else
  267. {
  268.  str += c;
  269.  fcin.read(&c,sizeof(char));
  270.  str += c;
  271. }
  272. }
  273. }
  274. int main()
  275. {
  276. Dictiory D("dictiory.txt","data.txt");
  277. //D.PrintDic();
  278.     D.SegmentWord("sou.txt");
  279. system("pause");
  280. return 0;
  281. }