c++实现之 -- 汉语词语的简单处理
好了,我们现在已经会怎样读入了,然后就是研究一下如何存储等一些细节上的的问题了。
首先,比较函数是不能传入char*的地址的,但是可以接受一个string类。
然而,如果是两个比较长的string类,要进行比较的话,时间复杂度会上升至O(min(length)),非常不合算。于是采用双哈希的办法,用h1、h2两个哈希值来表示特定字符串,冲突概率可以下降至基本忽略不计。不难发现双哈希的单词比较复杂度是O(2)的,大大减少了时间复杂度。
然后,就是采用什么容器进行存储。一般有两种:(不妨设哈希的使用的素数分别为p1和p2)
第一种是二维数组,第一维表示h1,第二维表示h2。为了节省空间第二维用vector进行存储,于是插入和查询的时间复杂度都是O(log(p2))。
第二种嘛,直接丢到map里,插入、查询的时间复杂度都是O(log(cnt)) (其中cnt表示不同单词个数)
于是我直接用了第二种,因为实现起来简单,而且复杂度基本相同。(因为vector常数大)
另外,c++的cin读入是非常喜闻乐见的慢,所以使用" ios::sync_with_stdio(false);"这句话关闭cin与stdio之间的同步缓冲,于是cin的速度和scanf就相差无几了。
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <map> #define TF second
using namespace std;
const int tot_file = ;
const int mod1 = ;
const int mod2 = ;
const int bin = << ;
struct Word {
string st;
int h1, h2; inline bool operator < (const Word &x) const {
return h1 == x.h1 ? h2 < x.h2 : h1 < x.h1;
} #define x (int) st[i]
#define Weight 3001
inline void calc_hash() {
int len = st.length(), tmp, i;
for (i = tmp = ; i < len; ++i)
((tmp *= Weight) += (x < ? x + bin : x)) %= mod1;
h1 = tmp;
for (i = tmp = ; i < len; ++i)
((tmp *= Weight) += (x < ? x + bin : x)) %= mod2;
h2 = tmp;
}
#undef x
#undef Weight
};
typedef map <Word, int> map_for_words;
typedef map_for_words :: iterator iter_for_words; map_for_words passage;
Word w;
string st; void read_in() {
ios::sync_with_stdio(false);
while (cin >> w.st) {
w.calc_hash();
passage[w] += ;
}
} int main() {
freopen("test.in", "r", stdin);
read_in();
iter_for_words it;
for (it = passage.begin(); it != passage.end(); ++it)
cout << it -> first.st << ' ' << it -> TF << endl;
return ;
}
效果(貌似还可以的说):
输入:
输出:
c++实现之 -- 汉语词语的简单处理的更多相关文章
- 基于TF-IDF值的汉语语义消歧算法
RT,学校课题需要233,没了 话说,窝直接做个链接的集合好了,方便以后查找 特征值提取之 -- TF-IDF值的简单介绍 汉语语义消歧之 -- 句子相似度 汉语语义消歧之 -- 词义消歧简介 c++ ...
- 19-python 自己建立词库并实现文章汉语词频统计
首先在网上下载一个汉语词典的txt文件, 汉语词典 1.用正则去掉词语的解释,即提取出所有汉语词语: import re def getHanYuCi(st): p = re.compile(r'[. ...
- 从海量文本中统计出前k个频率最高的词语
现有如下题目:有一个海量文本,存储的是汉语词语,要求从中找出前K个出现频率最高的词语,写出最优算法,兼顾时间和空间复杂度. 思路分析:熟悉搜索引擎的程序员,应该不是难题.用传统的HashMap是无法解 ...
- sentence patterns
第四部分 推理题 1.世界上每个角落的每个人都有立场,都有背景,都有推理性,能推理出一个人语言的真意,才成就了真正的推理能力: 2.换言之,如果你能通过一个人的说话推理出其身份职业,你的推理能 ...
- 大家一起来找茬(BUG)
大家一起来找茬(BUG) ----------目录---------- 一.上手体验 1.主界面 2.功能 二.程序的 BUG 三.必应词典的 BUG 1."每日一句"里的句子不能 ...
- 基于Android应用《玩转英语》(总报告)
基于Android应用<玩转英语> 摘 要 ...
- html和css的重难点知识
目录 html总难点总结: 1. 块级标签与内联标签的区别 1.1 块级标签: 1.2 内联标签: 2. 选择器 2.1 定义 2.2 选择器的分类 2.1 选择器的分类 3. css中margin, ...
- CSS padding margin border属性详解
图解CSS padding.margin.border属性W3C组织建议把所有网页上的对像都放在一个盒(box)中,设计师可以通过创建定义来控制这个盒的属性,这些对像包括段落.列表.标题.图片以及层. ...
- CSS中的margin、border、padding区别
CSS padding margin border属性详解 图解CSS padding.margin.border属性W3C组织建议把所有网页上的对像都放在一个盒(box)中,设计师可以通过创建定义来 ...
随机推荐
- Object-C : Block的实现方式
摘自:http://www.cnblogs.com/GarveyCalvin/p/4204167.html> Date : 2015-12-4 前言:我们可以把Block当作一个闭包函数,它可以 ...
- JAX-WS:背后的技术JAXB及传递Map
转载:http://www.programgo.com/article/98912703200/ 1.什么是JAX-WS JAX-WS (JavaTM API for XML-Based Web Se ...
- hdu4720Naive and Silly Muggles
链接 一直理解的最小覆盖圆就是外接圆..原来还要分钝角和锐角... 钝角的话就为最长边的中点,对于这题分别枚举一下外接圆以及中点的圆,判一下是不是在园外. #include <iostream& ...
- maven的聚合与继承5
一.聚合 如果我们想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合 1.1.聚合配置代码 1 <modules> 2 <module>模块一</module&g ...
- android模拟器中文乱码
问题:在xml文件中设置的中文能正确输出,但是在java文件中设置的中文会在模拟器上呈现乱码 解决方案:在build.gradle文件中添加一行代码 android {compileOptions.e ...
- 最大的LeftMax与rightMax之差绝对值
这两天去 牛客网 混了下,遇到的几道题都很有意思,尤其是今晚这道,比赛时不会做,后来看了别人的代码才突然想通的,题目链接: 最大的LeftMax与rightMax之差绝对值,大意是: 想了一晚都没想出 ...
- ajax跨域jsonp
<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8&qu ...
- [css]【转载】CSS样式分离之再分离
原文链接:http://www.zhangxinxu.com/wordpress/2010/07/css%E6%A0%B7%E5%BC%8F%E5%88%86%E7%A6%BB%E4%B9%8B%E5 ...
- mongodb数据库js查询
#健康风险-disease db.disease.find({versions:'2'}).forEach(function(item){ item.diseaseDetail && ...
- phalcon:非空字段不能在beforeCreate赋值,可以改用beforeValidationOnCreate
phalcon非空字段不能在beforeCreate赋值 碰到了这个问题,不知道什么原因记录一下. 表users: action_act 字段 varchar 10 not null,非空字段, 在 ...