最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語(yǔ)言中壓縮字符串的簡(jiǎn)單算法小結(jié)

 更新時(shí)間:2016年03月15日 14:35:20   作者:wuzhekai1985  
這篇文章主要介紹了C語(yǔ)言中可用于實(shí)現(xiàn)字符串壓縮的簡(jiǎn)單算法小結(jié),列舉了包括哈夫曼算法等三個(gè)核心的程序?qū)崿F(xiàn)算法,需要的朋友可以參考下

應(yīng)用中,經(jīng)常需要將字符串壓縮成一個(gè)整數(shù),即字符串散列。比如下面這些問(wèn)題:
(1)搜索引擎會(huì)通過(guò)日志文件把用戶每次檢索使用的所有檢索串都記錄下來(lái),每個(gè)查詢串的長(zhǎng)度為1-255字節(jié)。請(qǐng)找出最熱門的10個(gè)檢索串。
(2)有一個(gè)1G大小的一個(gè)文件,里面每一行是一個(gè)詞,詞的大小不超過(guò)16字節(jié),內(nèi)存限制大小是1M。返回頻數(shù)最高的100個(gè)詞。
(3)有10個(gè)文件,每個(gè)文件1G,每個(gè)文件的每一行存放的都是用戶的query,每個(gè)文件的query都可能重復(fù)。要求你按照query的頻度排序。
(4)給定a、b兩個(gè)文件,各存放50億個(gè)url,每個(gè)url各占64字節(jié),內(nèi)存限制是4G,讓你找出a、b文件共同的url。
(5)一個(gè)文本文件,大約有一萬(wàn)行,每行一個(gè)詞,要求統(tǒng)計(jì)出其中最頻繁出現(xiàn)的前10個(gè)詞。

這些問(wèn)題都需要將字符串壓縮成一個(gè)整數(shù),或者說(shuō)是散列到某個(gè)整數(shù) M 。然后再進(jìn)行取余操作,比如 M%16,就可以將該字符串放到編號(hào)為M%16的文件中,相同的字符串肯定是在同一個(gè)文件中。通過(guò)這種處理,就可以將一個(gè)大文件等價(jià)劃分成若干小文件,而對(duì)于小文件,就可以用常規(guī)的方法處理,內(nèi)排序、hash_map等等。最后將這些小文件的處理結(jié)果綜合起來(lái),就可以求得原問(wèn)題的解。
下面介紹一些字符串壓縮的算法。

方法1:最簡(jiǎn)單就是將所有字符加起來(lái),代碼如下:

unsigned long HashString(const char *pString, unsigned long tableSize)
{
 unsigned long hashValue = 0;
 while(*pString)
    hashValue += *pString++;
 return hashValue % tableSize;
}

分析:如果字符串的長(zhǎng)度有限,而散列表比較大的話,浪費(fèi)比較大。例如,如果字符串最長(zhǎng)為16字節(jié),那么用到的僅僅是散列表的前16*127=2032。假如散列表含2729項(xiàng),那么2032以后的項(xiàng)都用不到。

方法2:將上次計(jì)算出來(lái)的hash值左移5位(乘以32),再和當(dāng)前關(guān)鍵字相加,能得到較好的均勻分布的效果。

unsigned long HashString(const char *pString,unsigned long tableSize)
{
 unsigned long hashValue = 0;
 while (*pString)
 hashValue = (hashValue << 5) + *pString++;
 return hashValue % tableSize;
}

分析:這種方法需要遍歷整個(gè)字符串,如果字符串比較大,效率比較低。

方法3:利用哈夫曼算法,假設(shè)只有0-9這十個(gè)字符組成的字符串,我們借助哈夫曼算法,直接來(lái)看實(shí)例: 

#define Size 10 
int freq[Size]; 
string code[Size]; 
string word; 
struct Node 
{ 
 int id; 
 int freq; 
 Node *left; 
 Node *right; 
 Node(int freq_in):id(-1), freq(freq_in) 
 { 
  left = right = NULL; 
 } 
}; 
struct NodeLess 
{ 
 bool operator()(const Node *a, const Node *b) const 
 { 
  return a->freq < b->freq; 
 } 
}; 
 
void init() 
{ 
 for(int i = 0; i < Size; ++i) 
  freq[i] = 0; 
 for(int i = 0; i < word.size(); ++i) 
  ++freq[word[i]]; 
} 
void dfs(Node *root, string res) 
{ 
 if(root->id >= 0) 
  code[root->id] = res; 
 else 
 { 
  if(NULL != root->left) 
   dfs(root->left, res+"0"); 
  if(NULL != root->right) 
   dfs(root->right, res+"1"); 
 } 
} 
 
void deleteNodes(Node *root) 
{ 
 if(NULL == root) 
  return ; 
 if(NULL == root->left && NULL == root->right) 
  delete root; 
 else 
 { 
  deleteNodes(root->left); 
  deleteNodes(root->right); 
  delete root; 
 } 
} 
void BuildTree() 
{ 
 priority_queue<Node*, vector<Node*>, NodeLess> nodes; 
 for(int i = 0; i < Size; ++i) 
 { 
//0 == freq[i] 的情況未處理 
    Node *newNode = new Node(freq[i]); 
  newNode->id = i; 
  nodes.push(newNode); 
 } 
 while(nodes.size() > 1) 
 { 
  Node *left = nodes.top(); 
  nodes.pop(); 
  Node *right = nodes.top(); 
  nodes.pop(); 
  Node *newNode = new Node(left->freq + right->freq); 
    newNode->left = left; 
    newNode->right = right; 
    nodes.push(newNode); 
 } 
 Node *root = nodes.top(); 
 dfs(root, string("")); 
 deleteNodes(root); 
} 

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)停車場(chǎng)項(xiàng)目

    C語(yǔ)言實(shí)現(xiàn)停車場(chǎng)項(xiàng)目

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)停車場(chǎng)項(xiàng)目,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C++11如何實(shí)現(xiàn)無(wú)鎖隊(duì)列

    C++11如何實(shí)現(xiàn)無(wú)鎖隊(duì)列

    這篇文章主要介紹了C++11如何實(shí)現(xiàn)無(wú)鎖隊(duì)列,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • C語(yǔ)言開發(fā)實(shí)現(xiàn)井字棋及電腦落子優(yōu)化示例詳解

    C語(yǔ)言開發(fā)實(shí)現(xiàn)井字棋及電腦落子優(yōu)化示例詳解

    以前上課經(jīng)常和同桌玩起井字棋,那么我們就當(dāng)我們回憶童年,現(xiàn)在也用C語(yǔ)言來(lái)實(shí)現(xiàn)井字棋,本次代碼相對(duì)于初階的井字棋,在電腦下棋代碼部分做了優(yōu)化,使得電腦更加具有威脅
    2021-11-11
  • C語(yǔ)言實(shí)現(xiàn)棧的示例代碼

    C語(yǔ)言實(shí)現(xiàn)棧的示例代碼

    棧是一種特殊的線性表,只允許從一端進(jìn)出數(shù)據(jù),稱為后進(jìn)先出,先進(jìn)后出。本文主要為大家介紹了C語(yǔ)言實(shí)現(xiàn)棧的示例代碼,感興趣的可以了解一下
    2022-06-06
  • C語(yǔ)言函數(shù)的基本使用和遞歸詳解

    C語(yǔ)言函數(shù)的基本使用和遞歸詳解

    一個(gè)函數(shù)在它的函數(shù)體內(nèi)調(diào)用它自身稱為遞歸調(diào)用。這種函數(shù)稱為遞歸函數(shù)。C語(yǔ)言允許函數(shù)的遞歸調(diào)用。在遞歸調(diào)用中,主調(diào)函數(shù)又是被調(diào)函數(shù)。執(zhí)行遞歸函數(shù)將反復(fù)調(diào)用其自身,每調(diào)用一次就進(jìn)入新的一層
    2021-09-09
  • 如何通過(guò)wrap malloc定位C/C++的內(nèi)存泄漏問(wèn)題

    如何通過(guò)wrap malloc定位C/C++的內(nèi)存泄漏問(wèn)題

    用C/C++開發(fā)的程序執(zhí)行效率很高,但卻經(jīng)常受到內(nèi)存泄漏的困擾。本文提供一種通過(guò)wrap malloc查找memory leak的思路。
    2021-05-05
  • C++深入探究類與對(duì)象之友元與運(yùn)算符重載

    C++深入探究類與對(duì)象之友元與運(yùn)算符重載

    友元就是讓一個(gè)函數(shù)或者類,訪問(wèn)另一個(gè)類中的私有成員;打個(gè)比方,這相當(dāng)于是說(shuō):朋友是值得信任的,所以可以對(duì)他們公開一些自己的隱私,運(yùn)算符重載的實(shí)質(zhì)就是函數(shù)重載或函數(shù)多態(tài),運(yùn)算符重載是一種形式的C++多態(tài),目的在于讓人能夠用同名的函數(shù)來(lái)完成不同的基本操作
    2022-04-04
  • C/C++實(shí)現(xiàn)segy文件的讀取詳解

    C/C++實(shí)現(xiàn)segy文件的讀取詳解

    SEGY是地震數(shù)據(jù)一般以地震道為單位進(jìn)行組織,采用SEG-Y文件格式存儲(chǔ)。標(biāo)準(zhǔn)SEGY文件一般包括三部分:卷頭、道頭與地震道數(shù)據(jù)。本文將介紹利用C++讀取segy文件的方法,感興趣的可以了解一下
    2022-03-03
  • C語(yǔ)言結(jié)課設(shè)計(jì)之計(jì)算器功能

    C語(yǔ)言結(jié)課設(shè)計(jì)之計(jì)算器功能

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言結(jié)課設(shè)計(jì)之計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • 圖解AVL樹數(shù)據(jù)結(jié)構(gòu)輸入與輸出及實(shí)現(xiàn)示例

    圖解AVL樹數(shù)據(jù)結(jié)構(gòu)輸入與輸出及實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了C++圖解AVL樹數(shù)據(jù)結(jié)構(gòu)輸入與輸出操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05

最新評(píng)論

偏关县| 太康县| 麦盖提县| 拉孜县| 南京市| 安吉县| 元谋县| 曲水县| 新竹市| 湘潭市| 黎川县| 乌恰县| 中阳县| 察隅县| 广饶县| 綦江县| 遂溪县| 札达县| 霍山县| 遂溪县| 墨竹工卡县| 蓝山县| 许昌县| 万盛区| 汽车| 华坪县| 海城市| 揭阳市| 白水县| 罗源县| 绵阳市| 天等县| 弋阳县| 望江县| 商南县| 车险| 昌都县| 济南市| 嘉黎县| 香格里拉县| 鹿泉市|