zoukankan      html  css  js  c++  java
  • 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就相差无几了。

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <string>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <map>
     7 
     8 #define TF second
     9 using namespace std;
    10 const int tot_file = 4500000;
    11 const int mod1 = 19997;
    12 const int mod2 = 30001;
    13 const int bin = 1 << 9;    
    14 struct Word {
    15     string st;
    16     int h1, h2;
    17 
    18     inline bool operator < (const Word &x) const {
    19         return h1 == x.h1 ? h2 < x.h2 : h1 < x.h1;
    20     }
    21 
    22     #define x (int) st[i]
    23     #define Weight 3001
    24     inline void calc_hash() {
    25         int len = st.length(), tmp, i;
    26         for (i = tmp = 0; i < len; ++i)
    27             ((tmp *= Weight) += (x < 0 ? x + bin : x)) %= mod1;
    28         h1 = tmp;
    29         for (i = tmp = 0; i < len; ++i)
    30             ((tmp *= Weight) += (x < 0 ? x + bin : x)) %= mod2;
    31         h2 = tmp;
    32     }
    33     #undef x
    34     #undef Weight
    35 };
    36 typedef map <Word, int> map_for_words;
    37 typedef map_for_words :: iterator iter_for_words;
    38 
    39 map_for_words passage;
    40 Word w;
    41 string st;
    42 
    43 void read_in() {
    44     ios::sync_with_stdio(false);
    45     while (cin >> w.st) {
    46         w.calc_hash();
    47         passage[w] += 1;
    48     }
    49 }
    50 
    51 int main() {
    52     freopen("test.in", "r", stdin);
    53     read_in();
    54     iter_for_words it;
    55     for (it = passage.begin(); it != passage.end(); ++it)
    56         cout << it -> first.st << ' ' << it -> TF << endl;
    57     return 0;
    58 }    
    View Code

    效果(貌似还可以的说):

    输入:

    输出:

    (不要问我这界面怎么那么搞笑。。。这是终端的说)
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    Js 30 BOM
    js面向对象
    js模态窗口
    js默认行为(也称默认事件)
    框架的控件隐藏
    20150706 js之定时器
    sublime快捷方式和node.js
    js回调函数2
    Hibernate 多对一
    Hibernate入门之配置文件
  • 原文地址:https://www.cnblogs.com/rausen/p/4147965.html
Copyright © 2011-2022 走看看