演算法設計
⑴ 計算機演算法設計的關鍵是什麼
剛看到有人答鴕鳥演算法,的確是個很重要的演算法。
然後就想到了下面這個sorting演算法,雖然不怎麼重要,但是挺有意思的。
我覺得這有可能是我這輩子最喜歡的演算法了:
Sleep Sort
英語差不多的同學可以看一下Quora上的簡介
https://www.quora.com/What-is-sleep-sort
這套演算法是4chan上的某個精神病提出的
以下是代碼:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int c, char **v)
{
while (--c > 1 && !fork());
sleep(c = atoi(v[c]));
printf("%d\n", c);
wait(0);
return 0;
}
用GCC編譯,運行的時候把你想要sort的東西當成command line arguments送給可執行文件就行了
代碼來源:https://rosettacode.org/wiki/Sorting_algorithms/Sleep_sort
=====以下原答案=====
計算機科學里最重要的演算法就是你覺得最重要的演算法以外的所有演算法。←這是玩笑話
演算法是一整個體系,從divide and conquer,dynamic programming,greedy這樣的基本分類到randomized, linear programming這種奇怪的東西都是演算法體系裡重要的一環。演算法里還有一個大類就是data structure,這些東西環環相關。
初學演算法的同學就是要不斷的接觸,了解,分析這些亂七八糟的東西,最終達到看到不同的結構,不同的需求能夠選擇正確的工具。我的第一個演算法老師曾經這樣說過:there isn't a best algorithm for everything, choose the best tool for your problem
就拿你說的hash來看,你覺得key value pair到處都有用到,就覺得這個演算法最重要,O(1)的best case看起來也很誘人。可是能用的地方到底有多少?database天天用range query你告訴我你庫只有hash index?不能吧,所以B tree是不是很重要?演算法和優化是計算機科學里的一個大項,多少代人的研究成果讓你一個hash最重要給概括了,這樣是不是有種欽定的感覺?
演算法導論多看看,沒事的時候上leetcode做做題,多見識見識不同的演算法是如何應用的,每次選擇一個演算法/數據結構就問問自己為什麼這樣?是hash,是hash先,明明都是hash先來的……key value也好,O(1)也好,還是universal那傢伙也好...怎麼就做不了sssp呢?以後遇上奇怪的程序也不至於懵逼到:我一個linear programming,怎麼就跑maximum cardinality bipartite matching來了呢
至於到底什麼演算法最重要,能用到的都是最重要的,謝謝
⑵ 演算法設計-流程製作
我覺得這樣可能比較好理解一點 有三根柱子,標記為A, B, C 先要理解函數hanoi(n,A,B,C) 的意思是藉助於B柱子將A上面的n個盤子移到C上面,必須充分對應到各個參數。 如果想將n個盤子從A柱子移動到C柱子 可以分為這樣幾個步驟 (1)必須將A最下面也就是最大的那個盤子移動到C最下面 首先需要藉助C柱子將A上面的n-1個盤子移動到B上面 就是hanoi(n-1,A,C,B) 。 此時A上面只有一個最大的盤子,B上面按序放著n-1個盤子,C上面有0個盤子。 (2)將A上面的盤子移動到C上面,只需要1步。 此時A上面有0個盤子,B上面按序放著n-1個盤子,C上面只有一個最大的盤子。 (3)最後藉助於A柱子將B上面n-1個盤子移到C上面即可 就是hanoi(n-1,B,A,C) 。 所以實際上數學推導公式為f(n)=2f(n-1)+1,其中f(1)=1,f(n)表示將n個盤子從A柱子移到C柱子的步數
⑶ 演算法指什麼,演算法設計有什麼指標
通俗講就是解決問題的方法,用到計算機里,一般指程序設計中用到演算法比較多。專也是考研屬的時候計算機系的一個重點。
演算法是在有限步驟內求解某一問題所使用的一組定義明確的規則。通俗點說,就是計算機解題的過程。在這個過程中,無論是形成解題思路還是編寫程序,都是在實施某種演算法。前者是推理實現的演算法,後者是操作實現的演算法。
一個演算法應該具有以下五個重要的特徵:
有窮性: 一個演算法必須保證執行有限步之後結束;
確切性: 演算法的每一步驟必須有確切的定義;
輸入:一個演算法有0個或多個輸入,以刻畫運算對象的初始情況;
輸出:一個演算法有一個或多個輸出,以反映對輸入數據加工後的結果。沒有輸出的演算法是毫無意義的;
可行性: 演算法原則上能夠精確地運行,而且人們用筆和紙做有限次運算後即可完成。
http://www.cqzxzx.cn/it/noi/shuanfa/001.htm
⑷ 演算法設計有哪些方法
演算法設計常用的幾種方法是
1. 窮舉法
2. 貪心法
3. 分治法
4. 回溯法
5. 分枝限界法
6. 動態規劃法
⑸ 演算法設計的步驟不包含什麼
一、學習內容
1. 演算法設計中五大常用演算法
1) 分治法
設計思想:將一個難以直接解決的大問題分解成規模較小的相同問題,以便分而治之。
實際的應用:快速排序、歸並排序
分治法在每一層遞歸上的基本步驟:
①分解:將原問題分解為若干個規模較小、相互獨立、與原問題形式相同的子問題。
②解決:若子問題規模較小就直接解決,不然就遞歸解決各個子問題
③合並:將各個子問題的解合並為原問題的解
以快速排序為例理解分治法:
快速排序代碼:
public static void quickSort(int a[],int low,int high){
if(low < high){
int pivotpos = partition(a,low,high);
quickSort(a,low,pivotpos-1);
quickSort(a,pivotpos+1,high);
}
}
public static int partition(int a[],int low,int high){
int pivot = a[low];
while (low < high){
while (low < high && a[high] >= pivot){
--high;
}
a[low] = a[high];
while (low < high && a[low] <= pivot){
++low;
}
a[high] = a[low];
}
a[low] = pivot;
return low;
}
①分解:選取基準元素,將左右兩側進行劃分
②解決:分別將兩個子序列進行快速排序
③合並:將排好的子序列合並
以兩路合並排序為例理解分治法:(分治法中的合並在歸並排序中體現得更加清楚)
歸並排序代碼:
public static void merge(int a[],int low,int mid,int high){
int[] temp = new int[high-low+1];
int i = low;
int j = mid+1;
int k = 0;
while (i <= mid && j <= high){
if(a[i] < a[j]){
temp[k++] = a[i++];
}else {
temp[k++] = a[j++];
}
}
//把左邊剩下的移到數組中
while (i <= mid){
temp[k++] = a[i++];
}
//把右邊剩下的移到數組中
while (j <= high){
temp[k++] = a[j++];
}
//更新原數組
for (int x = 0;x <temp.length;x++){
a[x+low] = temp[x];
}
}
public static int[] mergeSort(int a[],int low,int high){
int mid = (low+high)/2;
if(low < high){
mergeSort(a,low,mid);
mergeSort(a,mid+1,high);
//左右合並
merge(a,low,mid,high);
}
return a;
}
①分解:將一個數組一刀切兩半,遞歸切,直到切成單個元素
②解決:單個元素合並成有序的小數組
③合並:小數組合並成大數組,最終合並完成
2) 動態規劃法
設計思想:最優化原理,即一個過程的最優決策具有這樣的性質:即無論其初始狀態和初始決策如何,其今後諸策略對以第一個決策所形成的狀態作為初始狀態的過程而言,必須構成最優策略
動態規劃法所要滿足的條件:
①問題中的狀態滿足最優化原理
②問題中的狀態必須滿足無後效性,無後效性指的是下一時刻的狀態只與當前的狀態 有關而與當前狀態的之前狀態無關。
動態規劃三要素:
①問題的階段
②每個階段的狀態
③從前一個階段轉換到後一個階段的遞推關系
實際的應用:0/1背包問題 最長公共子串問題
以最長公共子串問題為例理解動態規劃法:
定義dp[i][j]表示以A中第i個字元結尾的子串和B中第j個字元結尾的子串的最大公共子串,dp 的大小也為 (n + 1) x (m + 1) ,這多出來的一行和一列是第 0 行和第 0 列,初始化為 0,表示空字元串和另一字元串的子串的最長公共子串。
當我們要求dp[i][j]時,我們要先判斷A的第i個元素B的第j個元素是否相同即判斷A[i - 1]和 B[j -1]是否相同,如果相同它就是dp[i - 1][j- 1] + 1,相當於在兩個字元串都去掉一個字元時的最長公共子串再加 1;否則最長公共子串取0。所以整個問題的初始狀態為:
dp[i][0]=0,dp[0][j]=0
相應的狀態轉移方程為:
實現代碼:
public static int findLongest(String A,String B){
int n = A.length();
int m = B.length();
if(m == 0 || n == 0){
return 0;
}
int result = 0;
int[][] dp = new int[n+1][m+1];
//初始狀態
for(int i = 0; i <= n;i++){
dp[i][0] = 0;
}
for(int i = 0; i <= m;i++){
dp[0][i] = 0;
}
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
if(A.charAt(i-1) == B.charAt(j-1)){
dp[i][j] = dp[i-1][j-1]+1;
result = Math.max(result,dp[i][j]);
}else {
dp[i][j] = 0;
}
}
}
return result;
}
⑹ 演算法設計一般採用的是______方法。
A 粗到細 抽象到具體
⑺ 演算法設計的過程一般是什麼樣子
和你做數學題目的過程一樣,已知條件是什麼?已知量是什麼?要求什麼?需要輸出一個什麼結果?
演算法設計就是把問題解決步驟用計算機編程語言來表示出來
⑻ 演算法設計和編碼之間的區別是什麼哪種更難
演算法設計更難,編碼只是根據演算法的偽代碼去實現演算法。需要一些寫代碼的功底。
演算法設計更注重的是想法。基本上演算法設計出來了,寫程序就不難了。
演算法設計的工資比編碼的工資高得多,一個高中生就能編碼了。
在印度,程序員基本上是高中生。而中國的計算機本科生出來基本上做了程序員。