本文將深入探討演算法設計的原理。如果您不知道我指的是什麼,請繼續閱讀!
#當您聽到「演算法」這個詞時,您可能會透過以下三種方式之一做出回應:
- 您會立即知道並理解我們正在討論的內容,因為您學的是電腦科學。
- 您知道演算法是 Google 和 Facebook 等公司的主力,但您不太確定這個詞的意思。
- 您害怕地逃跑和躲藏,因為您所知道的關於演算法的一切都會讓您想起高中微積分的噩夢。
如果您是後兩者之一,那麼本文適合您。
到底什麼是演算法?
演算法不一定是一種特殊類型的操作。它們是概念性的,是您在程式碼中為達到特定目標而採取的一組步驟。
演算法通常被簡單地定義為「完成任務的指令」。它們也被稱為“食譜”。在《社群網戰》中,祖克柏需要一種演算法來讓 Facemash 發揮作用。如果你看過這部電影,你可能還記得在馬克宿舍的窗戶上看到了一個看起來像潦草的方程式的東西。但這個潦草的代數與馬克簡單的「熱門與否」網站有什麼關係呢?
演算法確實是指令。也許更準確的描述是演算法是有效完成任務的模式。祖克柏的 Facemash 是一個投票網站,用於確定某人相對於整個群體的吸引力,但用戶只能在兩個人之間進行選擇。馬克·祖克柏需要一種演算法來決定哪些人相互匹配,以及如何根據該人先前的歷史和先前的競爭者來評估投票的價值。這比簡單地計算每個人的選票需要更多的直覺。
例如,假設您想要建立一個演算法,將任何負數加 1,然後從任何正數中減去 1,並且對 0 不執行任何操作。您可以執行類似的操作(使用 JavaScript 式偽代碼) :
function addOrSubtractOne(number){ if (number < 0) { return number + 1 } else if (number < 0) { return number - 1 } else if (number == 0) { return 0; } }
您可能會對自己說:「這是一個函數。」你是對的。演算法不一定是一種特殊類型的操作。它們是概念性的 - 您在程式碼中為實現特定目標而採取的一組步驟。
那麼為什麼它們很重要呢?顯然,對數字加或減 1 是一件相當簡單的事情。
但是讓我們談談搜尋。要在數字數組中搜尋一個數字,您會怎麼做?一種簡單的方法是迭代該數字,將每個數字與您正在搜尋的數字進行檢查。但這不是一個有效的解決方案,而且可能的完成時間範圍很廣,因此當擴展到大型搜尋集時,它是一種不穩定且不可靠的搜尋方法。
function naiveSearch(needle, haystack){ for (var i = 0; i < haystack.length; i++){ if (haystack[i] == needle) { return needle; } } return false; }
幸運的是,我們可以在搜尋方面做得更好。
為什麼效率低?
要成為更好的演算法設計師,沒有比深入理解和欣賞演算法更好的方法了。
假設您的陣列有 50,000 個條目,並且您進行強力搜尋(即透過迭代整個陣列進行搜尋)。在最好的情況下,您正在搜尋的條目將是 50,000 個條目數組中的第一個條目。然而,在最壞的情況下,該演算法的完成時間將比最好的情況長 50,000 倍。
那麼什麼比較好?
相反,您可以使用二分搜尋進行搜尋。這涉及到對數組進行排序(我將讓您自己了解),然後將數組分成兩半,並檢查搜尋數是否大於或小於數組中的中間標記。如果它大於已排序數組的中間標記,那麼我們知道前半部可以被丟棄,因為搜尋到的數字不是數組的一部分。我們還可以透過定義數組的外部邊界並檢查搜尋到的數字是否存在於這些邊界之外來減少大量工作,如果存在,我們就採取了多次迭代操作並將其轉變轉化為單一迭代操作(在暴力演算法中需要50,000 次操作)。
sortedHaystack = recursiveSort(haystack); function bSearch(needle, sortedHaystack, firstIteration){ if (firstIteration){ if (needle > sortedHaystack.last || needle < sortedHaystack.first){ return false; } } if (haystack.length == 2){ if (needle == haystack[0]) { return haystack[0]; } else { return haystack[1]; } } if (needle < haystack[haystack.length/2]){ bSearch(needle, haystack[0..haystack.length/2 -1], false); } else { bSearch(needle, haystack[haystack.length/2..haystack.length], false); } }
聽起來相當複雜
採用單一二分搜尋演算法看似複雜的本質,並將其應用於數十億個可能的連結(如透過 Google 搜尋)。除此之外,讓我們對這些連結搜尋應用某種排名系統,以給出回應頁面的順序。更好的是,應用某種基於人工智慧社交模型的看似隨機的「建議」系統,旨在識別您可能想添加為朋友的人。
這讓我們更清楚地理解為什麼演算法不僅僅是函數的花哨名稱。在最好的情況下,它們是聰明、有效的方法來完成比最明顯的解決方案更高層次的直覺的事情。他們可以將超級電腦可能需要數年才能完成的任務轉變為在手機上幾秒鐘內完成的任務。
演算法如何應用在我身上?
對我們大多數開發人員來說,我們並不是每天都設計高階抽象演算法。
幸运的是,我们站在前辈开发人员的肩膀上,他们编写了本机排序函数,并允许我们以有效的方式使用 indexOf 搜索字符串中的子字符串。
块引用>但是我们确实处理我们自己的算法。我们每天创建
for
循环并编写函数;那么好的算法设计原则如何指导这些函数的编写呢?了解您的输入
算法设计的主要原则之一是,如果可能的话,以输入本身为您完成一些工作的方式构建算法。例如,如果您知道您的输入始终是数字,则不需要对字符串进行异常/检查,或将您的值强制转换为数字。如果您知道 JavaScript 中的
for
循环中的 DOM 元素每次都是相同的,那么您不应该在每次迭代中查询该元素。同样,在for
循环中,如果可以使用(更接近)简单操作完成相同的操作,则不应使用有开销的便利函数。// don't do this: for (var i = 1000; i > 0; i--){ $("#foo").append("<span>bar</span>"); } // do this instead var foo = $("#foo"); var s = ""; for(var i = 1000; i > 0; i--){ s += "<span>bar</span>"; } foo.append(s);如果您是一名 JavaScript 开发人员(并且使用 jQuery),并且您不知道上述函数在做什么以及它们有何显着不同,那么下一点适合您。
了解您的工具
在最好的情况下,[算法]是聪明、有效的方法来完成比最明显的解决方案更高水平的直觉。
很容易认为这是不言而喻的。然而,“知道如何编写 jQuery”和“理解 jQuery”之间是有区别的。了解您的工具意味着您了解每一行代码的作用,既立即(函数的返回值或方法的效果)又隐式(与运行库函数相关的开销,或者哪一个是最有效的)连接字符串的方法)。要编写出色的算法,了解较低级别函数或实用程序的性能非常重要,而不仅仅是它们的名称和实现。
了解环境
设计高效的算法是一项全身心投入的工作。除了将您的工具理解为一个独立的部分之外,您还必须了解它们与手头的更大系统交互的方式。例如,要完全理解特定应用程序中的 JavaScript,重要的是要了解跨浏览器场景中 JavaScript 的 DOM 和性能、可用内存如何影响渲染速度、您可能与之交互的服务器的结构(及其响应),以及无数其他无形的考虑因素,例如使用场景。
减少工作量
一般来说,算法设计的目标是用更少的步骤完成一项工作。 (也有一些例外,例如 Bcrypt 哈希。)编写代码时,请考虑计算机为达到目标而采取的所有简单操作。以下是一个简单的清单,可帮助您开始更高效的算法设计:
- 使用语言功能来减少操作(变量缓存、链接等)。
- 尽可能减少迭代循环嵌套。
- 尽可能在循环外部定义变量。
- 使用自动循环索引(如果可用)而不是手动索引。
- 使用巧妙的缩减技术(例如递归分治和查询优化)来最大限度地减少递归过程的规模。
学习先进技术
要成为一名更好的算法设计师,没有比深入理解和欣赏算法更好的方法了。
- 每周花一两个小时阅读《计算机编程的艺术》。
- 尝试 Facebook 编程挑战赛或 Google Codejam。
- 学习使用不同的算法技术解决同一问题。
- 通过使用较低级别的操作实现语言的内置函数(例如
.sort()
)来挑战自己。
结论
如果您在本文开始时还不知道什么是算法,那么希望您现在对这个有点难以捉摸的术语有了更具体的理解。作为专业开发人员,重要的是我们要了解我们编写的代码是可以分析和优化的,而且我们花时间对代码的性能进行分析也很重要。
你发现过什么有趣的算法练习题吗?也许是动态规划“背包问题”,或者“醉酒行走”?或者您可能知道 Ruby 中的一些递归最佳实践与 Python 中实现的相同函数不同。在评论中分享它们!
以上是深入了解演算法設計的基礎知識的詳細內容。更多資訊請關注PHP中文網其他相關文章!

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

WebStorm Mac版
好用的JavaScript開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能