盖报是什么生肖?
猜这个,其实是个很有意思的游戏。因为中国人总是有意无意地使用一些谐音字、象形字和成语来传达信息——当然,现在这种表达方式已经被翻译成英文了(例如“验证码”)。 所以,如果以文字作为信息载体,那么这个游戏就很有意思了!
我的方法就是,把要表达的词语(或者句子)用各种不同的方式写出来,然后计算每种方式出现的频率,出现频率最高的那几种方式所代表的字符就是我要找的答案。 当然,我这种方法是穷举所有可能的表达方式并计算频率,因此需要一些辅助算法来降低运算时间。首先我把每个句子分割成一个个的词,再根据词性给出相应的统计规则——例如对于“的”、“地”之类助词的统计就不算很严格。最后,我把这句话转化为数字序列,就可以输入电脑进行排队了。
为了加快排序速度,我还使用了分治法。先对原句子做分解,将其中含有同一个字的短语分为一组(这样处理的原因是,相同文字的不同排列方式的频率相差很大),然后对每组做排序,最后组合起排序结果就能得到整个句子的概率排序。
不过,这样处理的时间复杂度仍然是O(n2),当句子长度明显大于8个汉字时,计算机就要花相当长时间来计算了。所以,我又在原算法的基础上做一些优化,尽量缩短计算时间。 这里的关键思想在于,如果两个句子中相同位置的词能够组成一个语义单位的话,那么这两个句子就应该具有几乎相同的概率。例如在英语里,常常会出现一句话里多个动词的情况,这时可以根据动词的意指情况把几个动词分组,然后再整体看待两组之间的相似程度。而汉语中则经常存在动词和名词组在一起表示动作状态的情况,这时可以把动词和名词看成一个整体,与后面部分构成一个语义单位。这样做的好处是在不影响准确性的情况下大大减少了所需的数据量,从而缩短了计算时间。
实际上,我在做这个问题的时候并没有真正完成它,因为没有找到合适的数据集。后来我在CSDN上发布这篇文章后,有一位网友提供了很好的建议,就是在www.icwb.csu.cn网站上下载ICWBS数据库来进行实验。这是我第一次在网上看到有人和我做同样的问题,觉得很有意思,于是就照做了。 下面贴一下最终代码和运行的结果。
#include #include #define MAX_SIZE 1024 //一个字符串的最大长度 int charfreq[256]; //储存每一个字符出现次数得向量 int main() { int i,j; //i指向源文件每一行,j指向目标文件每一行 FILE *fp; /*创建一个用来存放结果的文件用于后续程序读写操作*/ fp=fopen("D:\\编程实现\\文字密码分析.txt","w"); for(i=0;i