编程珠玑第三章习题5——英语中的连字符问题

来源:互联网 发布:js设置div背景颜色 编辑:程序博客网 时间:2024/05/16 14:11
编程珠玑第三章习题5——英语中的连字符问题
问题:
本问题将处理一小部分用连字符连接的英语单词方面的问题。下面的规则列表描述了一些以字母c结尾的单词的有效连字符连接:et-ic al-is-tic s-tic p-tic -lyt-ic ot-ic an-tic n-tic c-tic at-ic h-nic n-ic m-ic l-lic b-lic -clic l-ic h-ic f-ic d-ic -bic a-ic -mac i-ac  应用该规则时,必须按照上述次序进行;从而导致了"ethnic"(遵循规则"h-nic")和"clinic"(不满足前一规则,但遵循"n-ic")。如果在某个函数中给定一个单词你必须返回后缀连字符,你该如何表示这样的规则呢

解法一:
  1. #include <iostream>  
  2. #include <cstring>  
  3. using namespace std;  
  4.   
  5. void swap(char * tem_word, int length){     //将单词首尾反序  
  6.     int i, times = length / 2;  
  7.     char ch;  
  8.     for(i = 0; i < times; ++ i){  
  9.         ch = tem_word[i];  
  10.         tem_word[i] = tem_word[length - 1 - i];  
  11.         tem_word[length - 1 - i] = ch;  
  12.     }  
  13. }  
  14. bool func(char * word, char * dest, int length){    //dest为欲求的word的后缀的反序  
  15.     bool flag = false;  
  16.     char arr[24][10] = {    //最长的单词的长度是 9,但列数为10,原因main函数中最后一句话  
  17.         "ci-td" , "cit-si-al" , "cit-p" , "ci-tyl-" , "ci-to" , "cit-na" , "cit-n" , "cit-c" , "cit-ta" ,  
  18.         "ci-ta" , "cin-h" , "ci-n" , "ci-m" , "cil-l" , "cil-b" , "cilc-" , "ci-l" , "ci-h" , "ci-f" ,  
  19.         "ci-d" , "cib-" , "ci-a" , "cam-" , "ca-i"  
  20.     };  
  21.     char arr1[24][8] = {  
  22.         "citd" , "citsial" , "citp" , "cityl" , "cito" , "citna" , "citn" , "citc" , "citta" ,  
  23.         "cita" , "cinh" , "cin" , "ci-m" , "cill" , "cilb" , "cilc" , "cil" , "cih" , "cif" ,  
  24.         "cid" , "cib" , "cia" , "cam" , "cai"  
  25.     };  
  26.     char * temp_str = new char[length + 1];  
  27.     strcpy(temp_str, word);  
  28.     swap(temp_str, length);
  29.     int i, len, j;  
  30.     for(i = 0; i < 24; ++ i){  
  31.         len = strlen(arr1[i]);  
  32.         if(len > length)  
  33.             continue;  
  34.         else{  
  35.             char * bk_str = new char[len + 1];  
  36.             for(j = 0; j < len; ++ j){  
  37.                 bk_str[j] = temp_str[j];  
  38.             }  
  39.             bk_str[j] = '\0' 
  40.             if(strcmp(bk_str, arr1[i]) == 0){  
  41.                 strcpy(dest, arr[i]);  
  42.                 flag = true;  
  43.                 break;  
  44.             }else  
  45.                 continue;             
  46.         }  
  47.     }  
  48.     delete temp_str;  
  49.     return flag;  
  50. }  
  51.   
  52.   
  53. int main(){  
  54.     char * word = new char[20];  
  55.     char * dest = new char[20];;  
  56.     cin >> word;  
  57.     if(func(word, dest, strlen(word))){ //如果为真说明找到  
  58.         swap(dest,strlen(dest));  
  59.         cout << dest << endl;  
  60.     }else{  
  61.         cout << "Cannot find the bk_str ! " << endl;  
  62.     }  
  63.     delete word;  
  64.     delete dest;   
  65.     return 0;  
  66. }  
  67. //result:  
  68. //clinic  
  69. // n-ic  
  70. //   
  71. //ethnic  
  72. // h-nic  


解法二:思路是:hash表中带hash。第一个以ic,tic等做hash。首先根据后缀找到hash_set,再把余下的字段,依次在hash_set中查找,并取出最长的。

  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<string>  
  4. #include<iterator>  
  5. #include<iostream>  
  6. #include<algorithm>  
  7. #include<hash_map>  
  8. #include<hash_set>  
  9.   
  10. usingnamespace std;   
  11. usingnamespace stdext;   
  12.   
  13. char *p[] = {"et-ic","al-is-tic","s-tic","p-tic","-lyt-ic","ot-ic","an-tic",  
  14. "n-tic","c-tic","at-ic","h-nic","n-ic","m-ic","l-lic","b-lic","-clic","l-ic",  
  15. "h-ic","f-ic","d-ic","-bic","a-ic","-mac","i-ac"};  
  16.   
  17.   
  18. void build_map(hash_map<string, hash_set<string> >& dict)   
  19. {  
  20. constint n = sizeof(p)/sizeof(char *);   
  21. for (int i = 0; i < n; ++i)   
  22. {  
  23. string line = p[i]; reverse(line.begin(), line.end());  
  24. int pos = line.find('-');  
  25. dict[line.substr(0, pos)].insert(line.substr(pos + 1, line.length() - pos - 1));   
  26. }  
  27. }  
  28.   
  29. string lookup(hash_map<string, hash_set<string> >& dict, string word)   
  30. {  
  31. string line = word; reverse(line.begin(), line.end());  
  32. int pos = line.find('-');  
  33. string ret;  
  34.   
  35. hash_map<string, hash_set<string> >::iterator iter;  
  36. if (dict.end() != (iter = dict.find(line.substr(0, pos))))   
  37. {  
  38. hash_set<string> &h = iter->second;  
  39. string temp = line.substr(pos + 1, line.length() - pos - 1);   
  40. for (int j = 1; j <= temp.length(); ++j)   
  41. {  
  42. string c = temp.substr(0, j);  
  43. if (h.find(c) != h.end() && c.length() > ret.length())   
  44. ret = c;  
  45. }  
  46. }  
  47. ret = iter->first +"-" + ret;  
  48. reverse(ret.begin(), ret.end());  
  49. return ret;   
  50. }  
  51. int main(void)  
  52. {  
  53. string sline;  
  54. hash_map<string, hash_set<string> > dict;  
  55. build_map(dict);  
  56.   
  57. while (cin >> sline)   
  58. {  
  59. cout << lookup(dict, sline) << endl;  
  60. }  
  61. return 0;   
  62. }  
有什么好的解法可以互相探讨,谢谢!