问题:
本问题将处理一小部分用连字符连接的英语单词方面的问题。下面的规则列表描述了一些以字母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")。如果在某个函数中给定一个单词你必须返回后缀连字符,你该如何表示这样的规则呢?
解法一:
- #include <iostream>
- #include <cstring>
- using namespace std;
-
- void swap(char * tem_word, int length){ //将单词首尾反序
- int i, times = length / 2;
- char ch;
- for(i = 0; i < times; ++ i){
- ch = tem_word[i];
- tem_word[i] = tem_word[length - 1 - i];
- tem_word[length - 1 - i] = ch;
- }
- }
- bool func(char * word, char * dest, int length){ //dest为欲求的word的后缀的反序
- bool flag = false;
- char arr[24][10] = { //最长的单词的长度是 9,但列数为10,原因main函数中最后一句话
- "ci-td" , "cit-si-al" , "cit-p" , "ci-tyl-" , "ci-to" , "cit-na" , "cit-n" , "cit-c" , "cit-ta" ,
- "ci-ta" , "cin-h" , "ci-n" , "ci-m" , "cil-l" , "cil-b" , "cilc-" , "ci-l" , "ci-h" , "ci-f" ,
- "ci-d" , "cib-" , "ci-a" , "cam-" , "ca-i"
- };
- char arr1[24][8] = {
- "citd" , "citsial" , "citp" , "cityl" , "cito" , "citna" , "citn" , "citc" , "citta" ,
- "cita" , "cinh" , "cin" , "ci-m" , "cill" , "cilb" , "cilc" , "cil" , "cih" , "cif" ,
- "cid" , "cib" , "cia" , "cam" , "cai"
- };
- char * temp_str = new char[length + 1];
- strcpy(temp_str, word);
- swap(temp_str, length);
- int i, len, j;
- for(i = 0; i < 24; ++ i){
- len = strlen(arr1[i]);
- if(len > length)
- continue;
- else{
- char * bk_str = new char[len + 1];
- for(j = 0; j < len; ++ j){
- bk_str[j] = temp_str[j];
- }
- bk_str[j] = '\0';
- if(strcmp(bk_str, arr1[i]) == 0){
- strcpy(dest, arr[i]);
- flag = true;
- break;
- }else
- continue;
- }
- }
- delete temp_str;
- return flag;
- }
-
-
- int main(){
- char * word = new char[20];
- char * dest = new char[20];;
- cin >> word;
- if(func(word, dest, strlen(word))){ //如果为真说明找到
- swap(dest,strlen(dest));
- cout << dest << endl;
- }else{
- cout << "Cannot find the bk_str ! " << endl;
- }
- delete word;
- delete dest;
- return 0;
- }
- //result:
- //clinic
- // n-ic
- //
- //ethnic
- // h-nic
解法二:思路是:hash表中带hash。第一个以ic,tic等做hash。首先根据后缀找到hash_set,再把余下的字段,依次在hash_set中查找,并取出最长的。
- #include<stdio.h>
- #include<stdlib.h>
- #include<string>
- #include<iterator>
- #include<iostream>
- #include<algorithm>
- #include<hash_map>
- #include<hash_set>
-
- usingnamespace std;
- usingnamespace stdext;
-
- char *p[] = {"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"};
-
-
- void build_map(hash_map<string, hash_set<string> >& dict)
- {
- constint n = sizeof(p)/sizeof(char *);
- for (int i = 0; i < n; ++i)
- {
- string line = p[i]; reverse(line.begin(), line.end());
- int pos = line.find('-');
- dict[line.substr(0, pos)].insert(line.substr(pos + 1, line.length() - pos - 1));
- }
- }
-
- string lookup(hash_map<string, hash_set<string> >& dict, string word)
- {
- string line = word; reverse(line.begin(), line.end());
- int pos = line.find('-');
- string ret;
-
- hash_map<string, hash_set<string> >::iterator iter;
- if (dict.end() != (iter = dict.find(line.substr(0, pos))))
- {
- hash_set<string> &h = iter->second;
- string temp = line.substr(pos + 1, line.length() - pos - 1);
- for (int j = 1; j <= temp.length(); ++j)
- {
- string c = temp.substr(0, j);
- if (h.find(c) != h.end() && c.length() > ret.length())
- ret = c;
- }
- }
- ret = iter->first +"-" + ret;
- reverse(ret.begin(), ret.end());
- return ret;
- }
- int main(void)
- {
- string sline;
- hash_map<string, hash_set<string> > dict;
- build_map(dict);
-
- while (cin >> sline)
- {
- cout << lookup(dict, sline) << endl;
- }
- return 0;
- }
有什么好的解法可以互相探讨,谢谢!