日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

从单词统计问题看面试

發布時間:2023/11/27 生活经验 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从单词统计问题看面试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文的很多內容來自網絡。如有錯誤,歡迎指出。

問題描寫敘述

?首先這里對單詞的界定是:以空白切割的字符序列。

單詞統計的問題能夠描寫敘述為:在一篇正常格式的英文文檔中(作為面試。這里并沒有提及中文分詞和單詞統計的問題),統計每一個單詞出現的次數。要求統計出現次數最多的N個單詞和對應的出現次數。

問題簡單明了。無需對字面做很多其它的解釋。

為什么面試官都喜歡考諸如此類的問題?

這類問題,大都有一個共同點:不僅要考慮數據的存儲,并且要考慮排序的問題。更重要的是。普通方法能夠解,偏偏面試官要找性能最好的、形式最優雅的。

怎么解?

??? 細致研讀一下題目,發現事實上僅僅有三件事情要做:1.單詞次數統計 2. 排序。

3.輸出前N個,當中問題3僅僅是問題2的衍生,因此能夠忽略。進一步分析發現,事實上這是典型的TOP K問題。拋開TOP K問題的經典解決方式不提,我們先看看一步步來看問題的解決思路。

1. Map

??? C++ Standard Template Library中提供了一種高效的容器Map, 它是一種鍵值對容器(關聯容器),因此能夠輕松存儲<單詞, 次數>這種鍵值序列,因而,最簡潔的解決方式能夠是這種:

int main(void){Map <String , int> wc;Map <String , int>::iterator j;String w;while( cin >> w ){wc[ w ] ++;}for( j = wc.begin(); j != wc.end(); j++ ){count << j->first <<  " : " j->second << "\n";}return 0;
}

因為Map的特性(數據插入時保證有序),因此輸出的結果事實上是依照key(也就是單詞)排好序的。所以,還須要對輸出的結果進行排序。至于怎么排序,sort。qsort,還是自建heap sort。不再贅述。

這樣已經非常好了,Map容器本身內建紅黑樹,使得插入的效率非常高。

可是,這樣真的好嗎?別忘了,面試官的要求更高。

2. Hashtable 神器。一鍵直達。效率再快一點

對于單詞和單詞次數的映射,除了使用Map外,還能夠使用自己定義的hash表,hash表的節點應該包含三個主要的域:指向單詞的指針或String,單詞的出現次數int。指向下一個節點的指針node *。

如果我們處理hash沖突的方案是鏈地址法。則:

Hash表node的定義為:

typedef struct node{char * word;int  count;node * next;
} node;

再次如果,處理的獨立的單詞個數不超過5w, 因此能夠選擇50021?這個質數作為hash表的大小。而hash算法。我們能夠選擇經常使用的BKDR算法(以31為累乘因子),這樣。能夠將單詞映射為一個unsigned int的整數:

#define HASH_SIZE 50021;
#define MUL_FACTOR 31;
node* mmap[HASH_SIZE];unsigned int hashCode( char *p){unsigned int result = 0;while(*p != '\0' ){result = result * MUL_FACTOR + *p++;}return result % HASH_SIZE;
}

??? 函數wordCount( char *p )用于將單詞和單詞的出現次數插入hash表中,假設hash表中有對應的節點,則添加單詞的次數并返回,否則須要加入新的節點到hash表的表頭并初始化次數為1.

 1 void wordCount( char *w ){
 2     unsigned int hashCode = hash( p );
 3     node * p;
 4 
 5     while( p = mmap[hashCode];p!=NULL;p = p->next ){
 6         if(strcmp(w, p->word) == 0){
 7             (p->count)++;
 8             return ;
 9         }
10     }
11 
12     node*q = (node*) malloc(sizeof(node));
13     q->count = 1;        
14     q->word = (char *) malloc(sizeof(w) + 1);
15     strcpy(q->word, w);
16     q->next = mmap[hashCode]; 
17     mmap[hashCode] = q;
18 }

相同,hash表僅僅是提供了數據存儲。并沒有排序。排序的問題,還須要你來完畢。

這樣似乎就完美了。

可素。倫家既不懂算法,又不會C++的容器。腫么辦 ?

3.? Shell版本號的單詞統計

Linux提供了非常多文本操作的工具。比方uniq, tr ,sort。而管道的存在,恰到優點的攻克了文本和單詞及中間處理結果須要存儲的問題。最重要的一點,這些工具是一系列的黑盒,你僅僅須要知道怎樣使用,而大不必去在乎內部實現的細節。

對于本題。用Linux 工具去處理,命令能夠是:

cat  word |
tr –cs a-zA-Z\’ ‘\n’ |
tr A-Z a-z |
sort |
uniq –c |
sort –k1,1nr |
head –n 10

?對該程序每一行的解釋:

  1. cat word ? ???????????? 將word文件的內容讀入緩存區。并作為下一個命令的輸入
  2. tr –cs a-zA-Z\’ ‘\n’ ? 將非字母字符轉換為換行符,保證一行一個單詞
  3. tr A-Z a-z ???????????? 將全部單詞轉為小寫形式。保證and和And是同一個單詞
  4. sort? ???????????????????? 按單詞排序
  5. uniq –c ???????????????? 統計每一個單詞的反復次數,也就相當于單詞的出現次數
  6. sort –k1,1nr ? ???????? 依照出現次數排序逆序排序。-n指定數字比較。-r指定逆序排序
  7. head –n 10 ? ? ??????? 輸出出現次數最多的10個單詞和它們的出現次數

寫到這里,突然想起若干年前去百度面試的時候。一個技術T5的大拿問的問題,也就是這道單詞統計的問題:一個文本中包括了非常多單詞,每行一個單詞,怎樣統計每一個單詞的次數?極其小白的我毫不含糊的回答:PHP腳本中每次讀一行。用關聯數組存單詞和單詞次數…….結果必定是慘烈的。

4.??? 文本處理的利器-AWK

既然提到了linux工具,那就不得不提一下awk(?k), awk是一個強大的文本分析處理工具。

Wiki上如是說:

??? AWK是一種優良的文本處理工具,Linux及Unix環境中現有的功能最強大的數據處理引擎之中的一個。AWK提供了極其強大的功能:能夠進行正則表達式的匹配。樣式裝入、流控制、數學運算符、進程控制語句甚至于內置的變量和函數。

它具備了一個完整的語言所應具有的差點兒全部精美特性。

??? 盡管僅是溢美之詞,可是不得不承認awk確實非常強大。

awk -F ' |,'  
'{for(i=1; i<=NF;i++){a[tolower($i)]++;}
}END{for(i in a)print i, a[i] |"sort -k2,2nr";
}'  word

???? gawk 3.1+中。能夠使用內置函數asortasorti對數組進行排序,只是排序的功能較弱。

比如asort(a) ,若a是關聯數組。asort的行為是僅僅對值排序,而鍵將被丟棄,取而代之的是新的1-n的數字索引。這能夠通過自己定義排序函數的方式或者結果通過管道傳遞給系統sort排序解決。

5.?? 數據庫版本號的方案。

我們這里如果文本已經是一行一個單詞。

數據庫表的基本結構為:

CREATE TABLE `test` (`word` varchar(20) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=gbk;

單詞入庫(也能夠load data in file):

awk '
BEGIN{sql="insert into test(word) values ";mysql="mysql -hxxxxxx -uxxxxx -pxxx test -e ";
}{for(i=1;i<=NF;i++){sq="\"" sql "('\''" $i"'\'')" "\"";print mysql sq |"sh -x";}
}' word

那么簡單的查詢:

select word,count(word) as total from test group by word order by total desc;

就能夠得到單詞的次數。

這樣的方法非常easy,由于數據庫替你完畢了全部統計和排序的工作,這也是為什么非常多人一旦有什么需求就求助于數據庫。

基于Key-Value的緩存系統(Redis等)也能夠完畢排序的功能。這里不再贅述。

思考

??? 假設你是面試官。你看好哪一種解法?算法和數據結構的。還是shell的,awk的。

就我而言,我覺得面試是挑選人才的。而不是靠所謂的“奇技淫巧”去為難別人的。

假設是我,看到有人用了shell的方式,或者awk的方式。我會給他高分。盡管算法是王道,但真的須要“一切從源代碼做起

?

參考文獻:
1. http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html
2.《shell腳本指南》
3.《編程珠璣》

轉載于:https://www.cnblogs.com/gccbuaa/p/7172407.html

總結

以上是生活随笔為你收集整理的从单词统计问题看面试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。