《編程珠璣(第2版?修訂版)》—第2章2.2節無處不在的二分搜索

本節書摘來自異步社區《編程珠璣(第2版?修訂版)》一書中的第2章2.2節無處不在的二分搜索,作者【美】Jon Bentley,更多章節內容可以訪問云棲社區“異步社區”公眾號查看。

2.2 無處不在的二分搜索
我想到的一個數在1到100之間,你來猜猜看。50?太小了。75?太大了。如此,游戲進行下去,直到你猜中我想到的數為止。如果我的整數位于1到n之間,那么你可以在log2n次之內猜中。如果n是1 000,10次就可以完成;如果n是100萬,則最多20次就可以完成。

這個例子引出了一項可以解決眾多編程問題的技術:二分搜索。初始條件是已知一個對象存在于一個給定的范圍內,而一次探測操作可以告訴我們該對象是否低于、等于或高于給定的位置。二分搜索通過重復探測當前范圍的中點來定位對象。如果一次探測沒有找到該對象,那么我們將當前范圍減半,然后繼續下一次探測。當找到所需要的對象或范圍為空時停止。

在程序設計中二分搜索最常見的應用是在有序數組中搜索元素。在查找項50時,算法進行如下探測。

眾所周知,二分搜索程序要正確運行很困難。在第4章中我們將詳細研究其代碼。

順序搜索在搜索一個具有n個元素的表時,平均需要進行n/2次比較,而二分搜索僅僅進行不超過log2n次的比較就可以完成。這在系統性能上會造成巨大的差異。下面的故事來自于《ACM通訊》的實例研究“TWA Reservation System”。

我們有一個執行線性搜索的程序,可以在1秒鐘內對一塊非常巨大的內存塊完成100次搜索。隨著網絡的增長,處理每條消息所需的平均CPU時間上升了0.3毫秒,這對我們來說是巨大的變化。我們發現問題的根源是線性搜索。把程序改為使用二分搜索以后,該問題消失了。
我在許多系統中也遇到過相同的問題。程序員在開始的時候使用簡單的順序搜索數據結構,這在開始的時候通常都足夠快。當搜索變得太慢的時候,對表進行排序并使用二分搜索通常可以消除瓶頸。

但是二分搜索的故事并沒有在快速搜索有序數組這里終止。Roy Weil將該技術應用于清理一個約1000行的輸入文件,其中僅包含一個錯誤行。很不幸,肉眼看不出錯誤行。只能通過在程序中運行文件的一個(起始)部分并且觀察到離奇錯誤的答案來辨別,這將會花費幾分鐘的時間。他的前任調試人員試圖通過每次運行整個程序中的少數幾行程序來找出錯誤行,但只在取得解決方案的道路上前進了一點點。Weil是如何僅僅運行10次程序就找到罪魁禍首的呢?

經過前面的熱身,我們現在來攻克問題A。輸入為順序文件(考慮磁帶或磁盤——雖然磁盤可以隨機讀寫,但是從頭至尾讀取文件通常會快得多)。文件包含最多40億個隨機排列的32位整數,而我們需要找出一個不存在于該文件中的32位整數。(至少缺少一個整數,因為一共有232也就是4 294 967 296個這樣的整數。)如果有足夠的內存,可以采用第1章中介紹的位圖技術,使用536 870 912個8位字節形成位圖來表示已看到的整數。然而,該問題還問到在僅有幾百個字節內存和幾個稀疏順序文件的情況下如何找到缺失的整數?為了采用二分搜索技術,就必須定義一個范圍、在該范圍內表示元素的方式以及用來確定哪一半范圍存在缺失整數的探測方法。如何來實現呢?

我們采用已知包含至少一個缺失元素的一系列整數作為范圍,并使用包含所有這些整數在內的文件表示這個范圍。靈機一動的結果是通過統計中間點之上和之下的元素來探測范圍:或者上面或者下面的范圍具有至多全部范圍的一半元素。由于整個范圍中有一個缺失元素,因此我們所需的那一半范圍中必然也包含缺失的元素。這些就是解決該問題的二分搜索算法所需要的主要想法。在翻閱答案查看Ed Reingold是如何做的以前,請嘗試將這些想法組織起來。

對于二分搜索技術在程序設計中的應用來說,這些應用僅僅是皮毛而已。求根程序使用二分搜索技術,通過連續地對分區間來求解單變量方程式(數值分析家稱之為對分法)。當答案11.9中的選擇算法區分出一個隨機元素以后,就對該元素一側的所有元素遞歸地調用自身(這是一種隨機二分搜索)。其他使用二分搜索的地方包括樹數據結構和程序調試(當程序沒有任何提示就意外中止時,你會從源代碼中哪一部分開始探測來定位錯誤語句呢?)。在上述的每個例子中,分析程序并對二分搜索算法做些許修改,可以帶給程序員功能強大的啊哈!靈機一動。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/456572.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/456572.shtml
英文地址,請注明出處:http://en.pswp.cn/news/456572.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JavaScript學習筆記(四)——jQuery插件開發與發布

jQuery插件就是以jQuery庫為基礎衍生出來的庫,jQuery插件的好處是封裝功能,提高了代碼的復用性,加快了開發速度,現在網絡上開源的jQuery插件非常多,隨著版本的不停迭代越來越穩定好用,在jQuery官網有許多插…

AIML元素詳細說明

目錄前言:1、簡介2、詳細說明總結: 目錄 前言: 智能客服客戶咨詢功能的實現主要依靠的就是Python的AIML庫,這里就先介紹下AIML。 詳細的使用教程可參考:https://github.com/andelf/PyAIML 目前大部分AIML只支持Py…

【解決】如何打開.ipynb文件

最近碰到文件名后綴為.ipynb文件,起初沒太在意這種文件格式,用Notepad打開之后看到也是類似于JSON格式的信息,以為也是為其他的一些文件服務的(類似于配置一些HTML文件的配置文件)。但是后來才發現這也是一種文本表示形…

《樹莓派學習指南(基于Linux)》——1.4 將Raspbian燒錄到SD卡

本節書摘來異步社區《樹莓派學習指南(基于Linux)》一書中的第1章,第1.4節,作者:【英】Peter Membrey ,【澳】David Hows ,更多章節內容可以訪問云棲社區“異步社區”公眾號查看 1.4 將Raspbian燒錄到SD卡 …

python單向鏈表和雙向鏈表的圖示代碼說明

圖示說明: 單向鏈表: insert、 remove、 update、pop方法 class Node:def __init__(self, data):self.data dataself.next Nonedef __str__(self):return str(self.data)# 通過單鏈表構建一個list的結構: 添加 刪除 插入 查找 獲取長…

不使用Ajax,如何實現表單提交不刷新頁面

不使用Ajax&#xff0c;如何實現表單提交不刷新頁面&#xff1f; 目前&#xff0c;我想到的是使用<iframe>&#xff0c;如果有其他的方式&#xff0c;后續再補。舉個栗子&#xff1a; 在表單上傳文件的時候必須設置enctype"multipart/form-data"表示表單既有文…

AIML知識庫數據匹配原理解析

目錄&#xff1a;前言&#xff1a;1、AIML系統工作流程2、AIML的核心推理機制3、推理舉例4、匹配規則及實踐中遇到的一些問題的解釋總結&#xff1a; 目錄&#xff1a; 前言&#xff1a; 參考&#xff1a;《Alice機理分析與應用研究》 關于AIML庫這里就不介紹了&#xff0c…

【Python】模擬面試技術面試題答

一、 python語法 1. 請說一下你對迭代器和生成器的區別&#xff1f; 2. 什么是線程安全&#xff1f; 3. 你所遵循的代碼規范是什么&#xff1f;請舉例說明其要求&#xff1f; 4. Python中怎么簡單的實現列表去重&#xff1f; 5. python 中 yield 的用法…

ROS機器人程序設計(原書第2版)2.3 理解ROS開源社區級

2.3 理解ROS開源社區級 ROS開源社區級的概念主要是ROS資源&#xff0c;其能夠通過獨立的網絡社區分享軟件和知識。這些資源包括&#xff1a; 發行版&#xff08;Distribution&#xff09; ROS發行版是可以獨立安裝、帶有版本號的一系列綜合功能包。ROS發行版像Linux發行版一樣…

Win7 U盤安裝Ubuntu16.04 雙系統

Win7系統下安裝Ubuntu系統&#xff0c;主要分為三步&#xff1a; 第1步&#xff1a;制作U盤啟動盤 第2步&#xff1a;安裝Ubuntu系統 第3步&#xff1a;創建啟動系統引導 第1步&#xff1a;制作U盤啟動盤 1.下載Ubuntu16.04安裝鏡像&#xff0c;官網地址&#xff1a;http://www…

Word2VecDoc2Vec總結

轉自&#xff1a;http://www.cnblogs.com/maybe2030/p/5427148.html 目錄&#xff1a;1、詞向量2、Distributed representation詞向量表示3、word2vec算法思想4、doc2vec算法思想5、Doc2Vec主要參數詳解總結&#xff1a; 目錄&#xff1a; 1、詞向量 自然語言理解的問題要轉…

ubantu安裝pycharm破解+Linux基礎簡介

一、課程簡介 linux服務器配置及常用命令 Ubuntu centos 開發軟件配置及服務環境的搭建 軟件的安裝和配置 mysql數據庫使用、monDB使用、redius的使用 git的使用 html/css 課程學習方式 表達訓練 學習方法&#xff1a; linux學習基本上都是命令和配置 命令要多敲多記 …

《游戲視頻主播手冊》——2.2 哪些人適合做游戲主播

本節書摘來自異步社區《游戲視頻主播手冊》一書中的第2章&#xff0c;第2.2節&#xff0c;作者 王巖&#xff0c;更多章節內容可以訪問云棲社區“異步社區”公眾號查看。 2.2 哪些人適合做游戲主播 據不完全統計&#xff0c;目前國內有超過26000名活躍的游戲主播。所謂“活躍的…

Doc2Vec實踐

目錄:前言&#xff1a;第一步&#xff1a;首先我們需要拿到對應的數據&#xff0c;相關的代碼如下&#xff1a;第二步&#xff1a;拿到對應的數據后&#xff0c;就開始訓練數據生成對應的model&#xff0c;對應的代碼如下&#xff1a;第三步&#xff1a;得到生成的model后&…

Linux常用命令全網最全

一、linux文件系統結構 sudo apt-get install treetree --help #查看幫助tree -L 1 #顯示文件目錄 rootubuntu16 /# tree -L 1 . #系統根目錄&#xff0c;有且只有一個根目錄 ├── bin #存放常見的命令 ├── boot #系統啟動文件和核心文件都在這個目錄…

《開源思索集》一Source Code + X

本節書摘來異步社區《開源思索集》一書中的第1章&#xff0c;作者&#xff1a; 莊表偉 責編&#xff1a; 楊海玲, 更多章節內容可以訪問云棲社區“異步社區”公眾號查看。 Source Code X 開源思索集最近&#xff0c;有一位來自學術界朋友&#xff0c;找到了我們這個開源的圈子…

機器學習中目標函數、損失函數以及正則項的通俗解釋

目錄&#xff1a;前言&#xff1a;1、什么是目標函數&#xff1f;2、損失函數3、正則化總結&#xff1a; 目錄&#xff1a; 前言&#xff1a; 今天看到一篇很精簡的文章來說明目標函數、損失函數以及正則項是什么。以下是文章正文。 轉自&#xff1a;https://xiaozhuanlan.…

Linux中的 硬鏈接ln和軟連接ln -s

文件都有文件名與數據&#xff0c;這在 Linux 上被分成兩個部分&#xff1a;用戶數據 (user data) 與元數據 (metadata)。用戶數據&#xff0c;即文件數據塊 (data block)&#xff0c;數據塊是記錄文件真實內容的地方&#xff1b;而元數據則是文件的附加屬性&#xff0c;如文件…

干貨分享!DevExpressv16.2最新版演示示例等你來收!(上)

2019獨角獸企業重金招聘Python工程師標準>>> 為解決大家找資源難的問題&#xff0c;EVGET聯合DevExpress控件中文網盤點熱門的DevExpress資訊、Demo示例、版本升級及下載&#xff0c;以及各種教程推薦等。更多下載及資訊也可以在DevExpress控件中文網中找到&#xf…

一文看懂哈夫曼樹與哈夫曼編碼

轉自&#xff1a;http://www.cnblogs.com/Jezze/archive/2011/12/23/2299884.html 在一般的數據結構的書中&#xff0c;樹的那章后面&#xff0c;著者一般都會介紹一下哈夫曼(HUFFMAN)樹和哈夫曼編碼。哈夫曼編碼是哈夫曼樹的一個應用。哈夫曼編碼應用廣泛&#xff0c;如JPEG中…