题目描述:请编写程序,根据指定的对应关系,把一个文本中的字符串替换成另外的字符串。
输入数据:程序读入已被命名为 text.txt 和 dict.txt 的两个输入数据文本文件, text.txt 为一个包含大量字符串(含中文)的文本,以 whitespace 为分隔符; dict.txt 为表示字符串( s1 )与字符串( s2 )的对应关系的另一个文本(含中文),大约在 1 万行左右,每行两个字符串(即 s1 和 s2 ),用一个 /t 或空格分隔。 dict.txt 中各行的 s1 没有排序,并有可能有重复,这时以最后出现的那次 s1 所对应的 s2 为准。 text.txt 和 dict.txt 中的每个字符串都可能包含除 whitespace 之外的任何字符。 text.txt 中的字符串必须和 dict.txt 中的某 s1 完全匹配才能被替换。(为便于调试,您可下载测试 text.txt 和 dict.txt 文件,实际运行时我们会使用不同内容的输入文件。)
输出数据:在标准输出上打印 text.txt 被 dict.txt 替换后了的整个文本。
评分标准:程序输出结果必须正确,内存使用越少越好,程序的执行时间越快越好。
关于这道题的一些想法,最直接的做法是读入字典,然后比较字符串是否出现过,没有出现过加入替换的字符串,出现过了则替换。可以考虑使用映射,使用STL里面的Map。然后读入text.txt字符串,找到Map的字符串,如果存在替换输出,没有的话,输出本身。
复杂度分析:构建字典的去重需要O(n^2),n为单词个数。然后替换需要时间为o(n*m),m为text.txt文本中单词的个数。而且里面会大量使用字符串比较函数strcmp。
其实,上面那种想法有点绕弯了,可以不去重的,“以最后出现的那次 s1 所对应的 s2 为准”,那么只要将dict.txt读到一个list里面,然后从List后面往前面比较,如果相同替换,不同打印本身。复杂度为O(n*m)。
这种方法我没有去实现。有兴趣的同学可以试试。
另外一种思路,其实这道题归根结底就是字符串比较的问题,text.txt文本中字符串S1,如果和dict.txt中的S2(最后出现的)相同,则替换。则不管S1和S2中包含那种字符,中文字符也好,英文字符也好,他们的字节流一定是相同的。(因为C++是GB2312编码,中文字符是2字节,英文字符是1字节的,而这中文字符的字节的取值范围是161-255,具体可以参见http://www.cublog.cn/u2/64540/showart_522529.html这里面中文字符的处理方式)。
那么我们可以构建一棵Trie树,树底下有256(一个字节取值范围为0-255)个节点,用于构建字典树,耗时为O(n)。事实上为o(n*k),k为字符串长度,上面字符串比较的时候没有考虑k,在这里也就忽略了。那么替换text.txt字符串的复杂度为o(m),同样忽略了k,速度跟上面那种方法比较应该能够取得很大的进步。代码实现如下:
百度之星05年第4题,我觉得同样可以考虑使用Trie树来实现,一遍构造,终生幸福。