算法的实现
‘壹’ 在计算机上实现算法要通过什么方式
摘要 计算机算法是以一步接一步的方式来详细描述计算机如何将输入转化为所要求的输出的过程,或者说算法是对计算机上执行的计算过程的具体描述。
‘贰’ 用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 函数
‘拾’ 算法我知道是什么,想问一下什么是算法的实现
算法的实现自然就是通过某种语言进行编程将这种算法应用到实际例子的解决上呀,比如递增数列,你就可以通过编程来实现它的求和呀,这就叫递增求和算法的实现