编程珠玑第三章习题5——英语中的连字符问题
2012-08-15 19:14
741 查看
编程珠玑第三章习题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")。如果在某个函数中给定一个单词你必须返回后缀连字符,你该如何表示这样的规则呢?
解法一:
#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;
}
有什么好的解法可以互相探讨,谢谢!
相关文章推荐
- 编程珠玑第三章—习题4(日期问题)
- 编程珠玑之第三章习题7
- 编程珠玑之第三章习题8
- 编程珠玑之第三章习题5
- 编程珠玑--------第三章习题笔记
- 编程珠玑之第三章习题3
- 编程珠玑之第三章习题6
- 编程珠玑之第12章习题1: 随机位问题
- 编程珠玑之第三章习题4
- 编程珠玑--------第五章习题笔记
- 第三章解决堆栈的编程问题
- 编程珠玑开篇--磁盘文件排序问题
- 【算法】数据结构与算法分析学习笔记——第三章习题选做Josephus问题
- 编程珠玑之第二章习题4
- 编程珠玑 第二章 习题6~9
- 编程珠玑: 12章 取样问题 12.3设计空间,程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复。 -------解题总结
- 程序员编程艺术:第三章续、Top K算法问题的实现
- 编程珠玑 第一章习题解答
- UNIX环境高级编程习题——第三章
- 编程珠玑中问题