嗯wwww一区二区三区视频,不卡的日韩播放视频在线观看,国产日本高清视频在线播放,国产精品无毒不卡久久久,国产片aⅴ在线观看国语

從奧軟件(上海)有限公司
了解算法設(shè)計(jì)原理

了解算法設(shè)計(jì)原理

算法不一定是一種特殊的操作。它們是概念性的,是您為實(shí)現(xiàn)特定目標(biāo)而在代碼中采取的一組步驟。

技術(shù)開(kāi)發(fā) 編程 技術(shù)框架 技術(shù)發(fā)展

 

了解算法設(shè)計(jì)原理

算法不一定是一種特殊的操作。它們是概念性的,是您為實(shí)現(xiàn)特定目標(biāo)而在代碼中采取的一組步驟。

本文將深入探討算法設(shè)計(jì)的原理。如果您不清楚我指的是什么,請(qǐng)繼續(xù)閱讀!

當(dāng)您聽(tīng)到“算法”一詞時(shí),您可能會(huì)以以下三種方式之一進(jìn)行響應(yīng):

  • 您會(huì)立即了解并理解我們?cè)谡f(shuō)什么,因?yàn)槟鷮W(xué)習(xí)過(guò)計(jì)算機(jī)科學(xué)。

  • 您知道算法是諸如Google和Facebook這樣的公司的主力軍,但您實(shí)際上不確定這個(gè)詞是什么意思。

  • 您奔跑而躲避恐懼,因?yàn)槟鷮?duì)算法的了解使您想起了高中微積分的噩夢(mèng)。

如果您是后兩者之一,那么本文適合您。

究竟是什么算法?

算法不一定是一種特殊的操作。它們是概念性的,是您為實(shí)現(xiàn)特定目標(biāo)而在代碼中采取的一組步驟。

通常以簡(jiǎn)單的術(shù)語(yǔ)將算法定義為“完成任務(wù)的指令”。他們也被稱為“食譜”。在《社交網(wǎng)絡(luò)》中,扎克伯格需要使用算法來(lái)使Facemash正常工作。如果您看過(guò)電影,可能還記得在Mark宿舍房間的窗戶上看到一個(gè)簡(jiǎn)陋的方程式。但是那個(gè)草的代數(shù)與Mark簡(jiǎn)單的“熱門(mén)與否”網(wǎng)站有什么關(guān)系?

算法確實(shí)是指令。也許更準(zhǔn)確的描述是算法是用于以有效方式完成任務(wù)的模式。扎克伯格的Facemash是一個(gè)投票網(wǎng)站,用于確定某人相對(duì)于整個(gè)人群的吸引力,但是只會(huì)為用戶提供兩個(gè)人之間的選擇權(quán)。馬克·扎克伯格(Mark Zuckerberg)需要一種算法,該算法可以確定哪些人可以相互匹配,以及如何相對(duì)于該人的先前歷史和先前的競(jìng)爭(zhēng)者來(lái)評(píng)估投票。這不僅需要簡(jiǎn)單地計(jì)算每個(gè)人的票數(shù),還需要更多的直覺(jué)。

例如,假設(shè)您要?jiǎng)?chuàng)建一種算法,將1加到任何負(fù)數(shù),再?gòu)?減去1,對(duì)0不做任何事情。您可能會(huì)執(zhí)行以下操作(在JavaScript式偽代碼中):


function addOrSubtractOne(number){

    if (number < 0) {

        return number + 1

    } else if (number < 0) {

        return number - 1

    } else if (number == 0) {

        return 0;

    }

}

您可能對(duì)自己說(shuō):“這是一個(gè)功能?!?而且你是對(duì)的。算法不一定是一種特殊的操作。它們是概念性的,您可以通過(guò)代碼中的一系列步驟來(lái)實(shí)現(xiàn)特定的目標(biāo)。

那么為什么他們有什么大不了的呢?顯然,對(duì)數(shù)字加1或減1是一件相當(dāng)簡(jiǎn)單的事情。

但是,讓我們先談一下搜索。要搜索一組數(shù)字中的數(shù)字,您會(huì)如何考慮?天真的方法是迭代數(shù)字,將每個(gè)數(shù)字與您要搜索的數(shù)字進(jìn)行比較。但這不是一個(gè)有效的解決方案,并且可能的完成時(shí)間范圍非常廣,因此在擴(kuò)展到大型搜索集時(shí),這是一種不穩(wěn)定且不可靠的搜索方法。


function naiveSearch(needle, haystack){

    for (var i = 0; i < haystack.length; i++){

        if (haystack[i] == needle) { return needle; }

    }

    return false;

}

幸運(yùn)的是,我們可以為此做得更好。

為什么效率低下?

對(duì)算法有深刻的理解和鑒賞,沒(méi)有比成為更好的算法設(shè)計(jì)者更好的方法了。

假設(shè)您的數(shù)組有50,000個(gè)條目,并且您進(jìn)行了蠻力搜索(即通過(guò)迭代整個(gè)數(shù)組進(jìn)行搜索)。在最佳情況下,您要搜索的條目將是50,000個(gè)條目數(shù)組中的第一個(gè)條目。但是,在最壞的情況下,該算法完成的時(shí)間將比在最壞的情況下長(zhǎng)50,000倍。

那有什么更好的呢?

相反,您將使用二進(jìn)制搜索進(jìn)行搜索。這涉及到對(duì)數(shù)組進(jìn)行排序(我將讓您自己學(xué)習(xí)),然后將數(shù)組分為兩半,并檢查搜索數(shù)是否大于或小于數(shù)組中途標(biāo)記。如果它大于已排序數(shù)組的中途標(biāo)記,那么我們知道前半部分可以被丟棄,因?yàn)樗阉鞯降臄?shù)字不屬于數(shù)組的一部分。我們還可以通過(guò)定義數(shù)組的外部邊界并檢查查找的數(shù)字是否存在于這些邊界之外來(lái)進(jìn)行大量工作,如果存在,我們將進(jìn)行多次迭代操作并將其翻轉(zhuǎn)一次迭代操作(在蠻力算法中,該操作將執(zhí)行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);

    }

}

聽(tīng)起來(lái)很復(fù)雜

考慮單個(gè)二進(jìn)制搜索算法看似復(fù)雜的性質(zhì),并將其應(yīng)用于數(shù)十億個(gè)可能的鏈接(通過(guò)Google搜索)。除此之外,讓我們對(duì)鏈接的搜索應(yīng)用某種排名系統(tǒng),以給出響應(yīng)頁(yè)面的順序。更好的是,基于人工智能社交模型應(yīng)用某種看似隨機(jī)的“建議”系統(tǒng),該系統(tǒng)旨在識(shí)別您可能希望添加為朋友的人。

這使我們對(duì)為什么算法不僅僅是函數(shù)的奇特名稱有了更清晰的了解。在最好的情況下,它們是聰明,有效的方法來(lái)完成某些工作,而這些方法比最明顯的解決方案需要更高的直覺(jué)。他們可以花上數(shù)年的時(shí)間才能完成一臺(tái)超級(jí)計(jì)算機(jī)的工作,然后將其變成一項(xiàng)在手機(jī)上只需幾秒鐘即可完成的任務(wù)。

算法如何應(yīng)用于我?

對(duì)于我們大多數(shù)開(kāi)發(fā)人員而言,我們并不是每天都在設(shè)計(jì)高級(jí)抽象算法。

幸運(yùn)的是,我們站在我們之前的開(kāi)發(fā)人員的肩膀上,他們編寫(xiě)了本機(jī)排序函數(shù),并允許我們以高效的方式在字符串中搜索帶有indexOf的子字符串。

但是我們確實(shí)要處理我們自己的算法。我們for每天創(chuàng)建循環(huán)并編寫(xiě)函數(shù);那么良好的算法設(shè)計(jì)原則如何可以幫助編寫(xiě)這些函數(shù)?

了解您的輸入

算法設(shè)計(jì)的主要原則之一是,如果可能,以某種方式構(gòu)建算法,使輸入本身可以為您完成一些工作。例如,如果您知道輸入將始終是數(shù)字,則無(wú)需對(duì)字符串進(jìn)行例外/檢查,也不必將值強(qiáng)制轉(zhuǎn)換為數(shù)字。如果您知道DOM元素for在JavaScript中的每次循環(huán)中都是相同的,則不應(yīng)該在每次迭代中都查詢?cè)撛亍M瑯?,在for循環(huán)中,如果可以使用(更接近)簡(jiǎn)單的操作來(lái)完成相同的事情,則不應(yīng)使用帶有開(kāi)銷的便捷函數(shù)。

// 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開(kāi)發(fā)人員(并且使用jQuery),并且您不知道上述函數(shù)的功能以及它們之間的顯著不同,那么接下來(lái)要講的就是您。

了解您的工具

在最好的情況下,[算法]是一種聰明,有效的方法來(lái)完成某些工作,而這種方法比最明顯的解決方案需要更高的直覺(jué)。

不言而喻,這很容易想到。但是,“知道如何編寫(xiě)jQuery”和“了解jQuery”之間是有區(qū)別的。了解您的工具意味著您立即了解每行代碼的作用(立即(函數(shù)的返回值或方法的效果)和隱式的(與運(yùn)行庫(kù)函數(shù)相關(guān)的開(kāi)銷多少),或者哪一種是最有效的連接字符串的方法)。要編寫(xiě)出色的算法,重要的是要了解低級(jí)函數(shù)或?qū)嵱贸绦虻男阅?,而不僅僅是它們的名稱和實(shí)現(xiàn)。

了解環(huán)境

設(shè)計(jì)高效的算法是一項(xiàng)全力以赴的工作。除了將您的工具理解為一個(gè)獨(dú)立的部分以外,您還必須了解它們與現(xiàn)有大型系統(tǒng)交互的方式。例如,要完全了解特定應(yīng)用程序中的JavaScript,了解跨瀏覽器場(chǎng)景中JavaScript的DOM和性能,可用內(nèi)存如何影響渲染速度,您可能與之交互的服務(wù)器結(jié)構(gòu)(及其響應(yīng)),以及許多其他無(wú)形的考慮因素,例如使用情況。

減少工作量

通常,算法設(shè)計(jì)的目標(biāo)是用更少的步驟來(lái)完成一項(xiàng)工作。(有一些例外,例如Bcrypt哈希。)在編寫(xiě)代碼時(shí),請(qǐng)考慮計(jì)算機(jī)為達(dá)到目標(biāo)所執(zhí)行的所有簡(jiǎn)單操作。這是一個(gè)簡(jiǎn)單的清單,可開(kāi)始著手進(jìn)行更有效的算法設(shè)計(jì):

  • 使用語(yǔ)言功能來(lái)減少操作(可變緩存,鏈接等)。

  • 盡可能減少迭代循環(huán)嵌套。

  • 盡可能在循環(huán)之外定義變量。

  • 使用自動(dòng)循環(huán)索引(如果有)而不是手動(dòng)索引。

  • 使用巧妙的歸約技術(shù),例如遞歸除法和征服以及查詢優(yōu)化,以最小化遞歸過(guò)程的大小。

學(xué)習(xí)先進(jìn)技術(shù)

對(duì)算法有深刻的理解和鑒賞,沒(méi)有比成為更好的算法設(shè)計(jì)者更好的方法了。

  • 每周花一兩個(gè)小時(shí)閱讀《計(jì)算機(jī)編程的藝術(shù)》。

  • 嘗試進(jìn)行Facebook編程挑戰(zhàn)賽或Google Codejam。

  • 學(xué)習(xí)使用不同的算法技術(shù)解決相同的問(wèn)題。

  • 通過(guò).sort()較低級(jí)別的操作實(shí)現(xiàn)語(yǔ)言的內(nèi)置功能(例如)來(lái)挑戰(zhàn)自己。

結(jié)論

如果您不了解本文開(kāi)頭的算法是什么,那么希望現(xiàn)在,您對(duì)這個(gè)難以捉摸的術(shù)語(yǔ)有了更具體的了解。作為專業(yè)開(kāi)發(fā)人員,重要的是我們了解可以對(duì)所編寫(xiě)的代碼進(jìn)行分析和優(yōu)化,并且花時(shí)間對(duì)代碼的性能進(jìn)行分析也很重要。

技術(shù)開(kāi)發(fā) 編程 技術(shù)框架 技術(shù)發(fā)展

平潭县| 永顺县| 竹北市| 哈尔滨市| 福建省| 吴堡县| 新余市| 郓城县| 乳源| 睢宁县| 柘荣县| 惠安县| 克山县| 滨州市| 绥中县| 海丰县| 桑日县| 呈贡县| 西平县| 喀喇沁旗| 稷山县| 达日县| 临高县| 舟山市| 深泽县| 宁津县| 内丘县| 怀化市| 喀喇沁旗| 荔浦县| 新化县| 库车县| 乌拉特后旗| 临夏县| 乌兰浩特市| 德清县| 云霄县| 吉安县| 崇仁县| 逊克县| 涿鹿县|