演算法的實現
『壹』 在計算機上實現演算法要通過什麼方式
摘要 計算機演算法是以一步接一步的方式來詳細描述計算機如何將輸入轉化為所要求的輸出的過程,或者說演算法是對計算機上執行的計算過程的具體描述。
『貳』 用java怎麼實現A*演算法
代碼實現(Java)
1.輸入
(1)代表地圖二值二維數組(0表示可通路,1表示路障)
int[][]maps={
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,1,1,0,0,0,0,0,0,1,1,1,0,0},
{0,0,0,1,0,0,0,0,0,1,1,0,0,0,0},
{0,0,0,1,0,0,0,0,1,1,0,0,0,0,0},
{0,0,0,1,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,1,0,0,0,0,1,0,0,0,0,0,0}
};123456789123456789
(2)按照二維數組的特點,坐標原點在左上角,所以y是高,x是寬,y向下遞增,x向右遞增,我們將x和y封裝成一個類,好傳參,重寫equals方法比較坐標(x,y)是不是同一個。
publicclassCoord
{
publicintx;
publicinty;
publicCoord(intx,inty)
{
this.x=x;
this.y=y;
}
@Override
publicbooleanequals(Objectobj)
{
if(obj==null)returnfalse;
if(objinstanceofCoord)
{
Coordc=(Coord)obj;
returnx==c.x&&y==c.y;
}
returnfalse;
}
}2223
(3)封裝路徑結點類,欄位包括:坐標、G值、F值、父結點,實現Comparable介面,方便優先隊列排序。
<Node>
{
publicCoordcoord;//坐標
publicNodeparent;//父結點
publicintG;//G:是個准確的值,是起點到當前結點的代價
publicintH;//H:是個估值,當前結點到目的結點的估計代價
publicNode(intx,inty)
{
this.coord=newCoord(x,y);
}
publicNode(Coordcoord,Nodeparent,intg,inth)
{
this.coord=coord;
this.parent=parent;
G=g;
H=h;
}
@Override
publicintcompareTo(Nodeo)
{
if(o==null)return-1;
if(G+H>o.G+o.H)
return1;
elseif(G+H<o.G+o.H)return-1;
return0;
}
}
(4)最後一個數據結構是A星演算法輸入的所有數據,封裝在一起,傳參方便。:grin:
publicclassMapInfo
{
publicint[][]maps;//二維數組的地圖
publicintwidth;//地圖的寬
publicinthight;//地圖的高
publicNodestart;//起始結點
publicNodeend;//最終結點
publicMapInfo(int[][]maps,intwidth,inthight,Nodestart,Nodeend)
{
this.maps=maps;
this.width=width;
this.hight=hight;
this.start=start;
this.end=end;
}
}
2.處理
(1)在演算法里需要定義幾個常量來確定:二維數組中哪個值表示障礙物、二維數組中繪制路徑的代表值、計算G值需要的橫縱移動代價和斜移動代價。
publicfinalstaticintBAR=1;//障礙值
publicfinalstaticintPATH=2;//路徑
publicfinalstaticintDIRECT_VALUE=10;//橫豎移動代價
publicfinalstaticintOBLIQUE_VALUE=14;//斜移動代價12341234
(2)定義兩個輔助表:Open表和Close表。Open表的使用是需要取最小值,在這里我們使用Java工具包中的優先隊列PriorityQueue,Close只是用來保存結點,沒其他特殊用途,就用ArrayList。
Queue<Node>openList=newPriorityQueue<Node>();//優先隊列(升序)
List<Node>closeList=newArrayList<Node>();1212
(3)定義幾個布爾判斷方法:最終結點的判斷、結點能否加入open表的判斷、結點是否在Close表中的判斷。
/**
*判斷結點是否是最終結點
*/
privatebooleanisEndNode(Coordend,Coordcoord)
{
returncoord!=null&&end.equals(coord);
}
/**
*判斷結點能否放入Open列表
*/
(MapInfomapInfo,intx,inty)
{
//是否在地圖中
if(x<0||x>=mapInfo.width||y<0||y>=mapInfo.hight)returnfalse;
//判斷是否是不可通過的結點
if(mapInfo.maps[y][x]==BAR)returnfalse;
//判斷結點是否存在close表
if(isCoordInClose(x,y))returnfalse;
returntrue;
}
/**
*判斷坐標是否在close表中
*/
privatebooleanisCoordInClose(Coordcoord)
{
returncoord!=null&&isCoordInClose(coord.x,coord.y);
}
/**
*判斷坐標是否在close表中
*/
privatebooleanisCoordInClose(intx,inty)
{
if(closeList.isEmpty())returnfalse;
for(Nodenode:closeList)
{
if(node.coord.x==x&&node.coord.y==y)
{
returntrue;
}
}
returnfalse;
}353637383940414243444546
(4)計算H值,「曼哈頓」法,坐標分別取差值相加
privateintcalcH(Coordend,Coordcoord)
{
returnMath.abs(end.x-coord.x)+Math.abs(end.y-coord.y);
}12341234
(5)從Open列表中查找結點
privateNodefindNodeInOpen(Coordcoord)
{
if(coord==null||openList.isEmpty())returnnull;
for(Nodenode:openList)
{
if(node.coord.equals(coord))
{
returnnode;
}
}
returnnull;
}
(6)添加鄰結點到Open表
/**
*添加所有鄰結點到open表
*/
(MapInfomapInfo,Nodecurrent)
{
intx=current.coord.x;
inty=current.coord.y;
//左
addNeighborNodeInOpen(mapInfo,current,x-1,y,DIRECT_VALUE);
//上
addNeighborNodeInOpen(mapInfo,current,x,y-1,DIRECT_VALUE);
//右
addNeighborNodeInOpen(mapInfo,current,x+1,y,DIRECT_VALUE);
//下
addNeighborNodeInOpen(mapInfo,current,x,y+1,DIRECT_VALUE);
//左上
addNeighborNodeInOpen(mapInfo,current,x-1,y-1,OBLIQUE_VALUE);
//右上
addNeighborNodeInOpen(mapInfo,current,x+1,y-1,OBLIQUE_VALUE);
//右下
addNeighborNodeInOpen(mapInfo,current,x+1,y+1,OBLIQUE_VALUE);
//左下
addNeighborNodeInOpen(mapInfo,current,x-1,y+1,OBLIQUE_VALUE);
}
/**
*添加一個鄰結點到open表
*/
(MapInfomapInfo,Nodecurrent,intx,inty,intvalue)
{
if(canAddNodeToOpen(mapInfo,x,y))
{
Nodeend=mapInfo.end;
Coordcoord=newCoord(x,y);
intG=current.G+value;//計算鄰結點的G值
Nodechild=findNodeInOpen(coord);
if(child==null)
{
intH=calcH(end.coord,coord);//計算H值
if(isEndNode(end.coord,coord))
{
child=end;
child.parent=current;
child.G=G;
child.H=H;
}
else
{
child=newNode(coord,current,G,H);
}
openList.add(child);
}
elseif(child.G>G)
{
child.G=G;
child.parent=current;
//重新調整堆
openList.add(child);
}
}
}85960618596061
(7)回溯法繪制路徑
privatevoiddrawPath(int[][]maps,Nodeend)
{
if(end==null||maps==null)return;
System.out.println("總代價:"+end.G);
while(end!=null)
{
Coordc=end.coord;
maps[c.y][c.x]=PATH;
end=end.parent;
}
}12345678910111234567891011
(8)開始演算法,循環移動結點尋找路徑,設定循環結束條件,Open表為空或者最終結點在Close表
publicvoidstart(MapInfomapInfo)
{
if(mapInfo==null)return;
//clean
openList.clear();
closeList.clear();
//開始搜索
openList.add(mapInfo.start);
moveNodes(mapInfo);
}
/**
*移動當前結點
*/
privatevoidmoveNodes(MapInfomapInfo)
{
while(!openList.isEmpty())
{
if(isCoordInClose(mapInfo.end.coord))
{
drawPath(mapInfo.maps,mapInfo.end);
break;
}
Nodecurrent=openList.poll();
closeList.add(current);
addNeighborNodeInOpen(mapInfo,current);
}
}
『叄』 實現演算法:
輸出成文件
C++實現
代碼:
#define_author"Reskip"
#define_CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
usingnamespacestd;
intencode(intx)
{
returnx*x+x*3+5;
}
intmain()
{
stringinput;
cin>>input;
freopen("save.txt","w",stdout);
for(chari:input)
{
cout<<encode(i)<<"";
}
return0;
}
『肆』 演算法實現
多看一些源代碼最好,先動手編一些簡單的程序,程序能力的提高都是靠看靠編出來的,理論不用很到位的面面具到的都非常懂會用最好,遇到問題會查閱資料。參考書籍的話:c就是譚浩強那本比較經典了,外國書是好但看起來費勁。c++就清華的潛能也不錯。你直接學《數據結構和演算法分析設計》這門課不太合理,因為得有一些基礎和編程經驗在學會更好一些。
多去csdn學習,多尋找一些好的源代碼看看。這樣學起來很快而且不枯燥,如果一味得看書你會煩得不行也沒有盡頭,邊學邊練習會極大增強信心。
『伍』 演算法如何實現
我的方法比較笨...只限4個數,沒有第一個的大哥哥寫的好,第2個弟弟寫的是錯的,偶試過~我寫的為:
main()
{
char a,b,c,d,e,f,g,h;
printf("請輸入4個數");
scanf("%c,%c,%c,%c\n",&a,&b,&c,&d);
a=e;
b=f;
c=g;
d=h;
printf("四個數倒過來讀為:%c,%c,%c,%c\n",h,g,f,e);
}
(僅供參考)不過給我分我也不介意~~呵呵~~~
『陸』 怎樣實現以下演算法
死循環相信沒什麼問題,這個題目就是隨機生成數據,然後找出是否有相同的數據的過程。如果是簡單的循環類代碼,就是類似窮舉法,一個個比較的過程;但是如果寫的優雅一些,實際上是一個排序過程。
我們來回憶一下排序的過程,從最簡單的冒泡、選擇,到最高級的快排、歸並,每一個排序實際上都進行了比較。那麼我們只需要在自定義的比較函數中對值進行輸出即可。
一般語言中都會內置排序函數,例如C的qsort、JavaScript的Array.prototype.sort、PHP的usort等。都支持傳入自定義的比較函數。下面以C舉例:
#include<stdlib.h>
#include<stdio.h>
#defineNUM20
inthas_equals=0;
typedefstructitem{/*數據元素結構體*/
intval;/*整數值,用於比較*/
intidx;/*記錄初始化時的位置,用於輸出用*/
}Item;
voidinitData(Item*arr,intlen){
inti;
printf("======RANDOMDATA====== ");
for(i=0;i<len;i++){
arr[i].val=rand()%100;/*一百以內的隨機數*/
printf("%d",arr[i].val);
arr[i].idx=i;
}
printf(" ");
}
intmyCmp(constvoid*va,constvoid*vb){
Item*a=(Item*)va;
Item*b=(Item*)vb;
if(a->val==b->val){/*兩個值相等,輸出*/
printf("FoundEquals:items[%d]==items[%d]==%d ",
a->idx,b->idx,a->val);
has_equals=1;/*標記找到相等的值*/
}
returna->val-b->val;
}
voidmain(){
Itemitems[NUM];
while(1){
has_equals=0;/*重置找到重復標記*/
initData(items,NUM);
qsort(items,NUM,sizeof(Item),myCmp);
if(!has_equals){
printf("++++++EveryItemisunique++++++ ");
break;
}
}
printf("Bye. ");
}
當數據有重復的時候會輸出重復項,並標記重復標志。C語言中沒有Exception機制,所以排序完成後再進行處理,不能中斷排序過程(也可以使用LongJump)。其他語言中都有Exception機制,可以直接在檢查到第一個相等之後就拋異常,外層捕獲異常做邏輯即可。
『柒』 怎麼用代碼實現一個具體演算法,思路是怎麼樣的
就和做方程一樣,我自己的感覺。語言之類的都是工具
比如C
你要描述一個z=x+y的程序,要輸出z的話。那首先必須x y有一個值吧,那你得通過鍵盤給他輸入一個值,或者直接賦一個值給他。當x和y都有值了,計算機就能識別+,=這兩個運算符號,把兩個值相加,然後通過=賦給z。最後,你剩下的就是輸出z的值了。
其實,其他的演算法也差不多,只是你練習少了而已。代碼記住要多寫,等你熟練了,不會覺得如何描述演算法有什麼困難的。
『捌』 演算法的實現就是編程嗎
演算法只能說是編程的一部分。主要是編程思想。
『玖』 演算法的實現方式有
b 函數
『拾』 演算法我知道是什麼,想問一下什麼是演算法的實現
演算法的實現自然就是通過某種語言進行編程將這種演算法應用到實際例子的解決上呀,比如遞增數列,你就可以通過編程來實現它的求和呀,這就叫遞增求和演算法的實現