三角形问题.docx
《三角形问题.docx》由会员分享,可在线阅读,更多相关《三角形问题.docx(10页珍藏版)》请在冰豆网上搜索。
三角形问题
《算法设计与分析》
上机实验报告
专业
软件工程
班级
软件1101
学号
04113035
学生姓名
付添
完成日期
2013-11-05
1.上机题目及实验环境
1.1上机题目:
数字三角形问题
1.2实验环境:
CPU:
Intel
内存:
4G
操作系统:
windowsxp
软件平台:
vc6.0
2.算法设计与分析
要设计从三角形的顶至底的一条最长路径,可以先计算出由顶部到三角形的倒数第二行的最长路径,然后要算出倒数第二行的一条最长路径时可求的他的上一行的最长路径,以此类推找出他的一条最长路径。
首先用二维数组来存储三角形中的数字,判断出第一列元素的父节点可以确定为是他的前一个元素,其对角线上的元素的父节点都是他上一个对角线的位置上的元素,所以,设置另一个二维数组来存储他们的和值,对于中间元素,由于存在两个父节点,所以比较他与他的两个父节点的和值的大小,将较大数存入到该数组中,最后比较数组最后一行元素的大小,来判断最大路径和的大小。
3.核心代码
sum1=a[0][0];
for(i=1;i{
for(j=0;j<=i;j++)
{
if(j==0)//第一列不用比较直接一次累加并一次保存
{
sum+=a[i][0];
b[i][0]=sum;
}
else
{
if(j==i)//处于对角线不用比较直接一次累加并一次保存
{
sum1+=a[i][i];
b[i][i]=sum1;
}
else
{
max=b[i-1][j-1]>b[i-1][j]?
b[i-1][j-1]:
b[i-1][j];//比较上面两个节点的大小
b[i][j]=max+a[i][j];
}
}
}
}
printf("最大路径长为:
%d\n",maxz);
输出路径的代码显示
maxz=0;
for(i=0;iif(b[count-1][i]>maxz)
{
maxz=b[count-1][i];
x=count-1;
y=i;
}
lu[x]=a[x][y];
while(x>0)//从下往上找出路径
{
cha=b[x][y]-a[x][y];
if(b[x-1][y-1]==cha)
{
lu[x-1]=a[x-1][y-1];
x=x-1;
y=y-1;
}
if(b[x-1][y]==cha)
{
lu[x-1]=a[x-1][y];
x=x-1;
}
}
printf("这条路的节点为\n");
for(i=0;i<=count-1;i++)
{
printf("%d",lu[i]);
}
4.运行与调试
图1.文件中存的是比较简单的数字情况
图2文件中存的是比较复杂的数组情况
图3文件中的数组
5.结果分析和小结
(1)对结果的分析。
分析结果可以采用图或者表的形式给出。
这个结果就是正确的。
由于这个数字三角问题相对来说比较简单,编程的时候遇到的问题比较少。
就是开始的构思的时候想的是采用两种结构形式存加到当前的值。
一种是报告中的数组,一种是结构体,Left,right分别表示从左边下来,以及从右边下来,第一例存的话left=-1,对角线存的话right=-1;
两种都试着写了一下。
不过最检查选择用数组的形式,因为到目前为止我写代码用数组的频率比较高,总感觉数组方便,好用。
(2)本次上机实验的收获、心得体会。
通过本次上机使得我对动态规划法的最优子结构方法又有了更好的掌握,在前两次上机的基础上,学会更好的利用动态规划解决问题,,也深深地体会到动态的高效性,编程的时候也遇到各种问题,比如读字符上,最后通过查资料解决,老师说我的编程风格也要注意一下,比如写注释,这次我也尽量写一些注释,慢慢来养成写注释的习惯,当然还有许多注意的问题,我会慢慢改正。
总之,通过本次试验加深了对最优子结构的理解,使得在以后的学习中能够更好地解决我们遇到的问题。
附录(C/C++源代码)
列出程序源码。
程序设计时注意设计风格。
#include
#include
#defineN50
intshiftnumber(charc)//将字符转化为数字
{
intnumber;
number=c-'0';
returnnumber;
}
main()
{
charstringcount,ch;
inti,j,count,a[N][N],b[N][N]={0},sum,sum1,max,maxz,x,lu[N],y,cha;
FILE*fp,*fp1;
fp=fopen("D:
\\input.txt","rt");//打开文件
if(fp==NULL)
{
printf("文件打开失败");
exit
(1);
}
fscanf(fp,"%c",&stringcount);
count=shiftnumber(stringcount);//将字符转化为字符串
printf("文件中数字显示:
\n");
printf("%d\n",count);
for(i=0;i<=count-1;i++)
{
for(j=0;j<=i;j++)
{
fscanf(fp,"%c",&ch);
fscanf(fp,"%d",&a[i][j]);
printf("%d",a[i][j]);
}
printf("\n");
}
printf("二维数组的信息显示:
\n");
for(i=0;i<=count-1;i++)
{
for(j=0;j<=i;j++)
printf("%d",a[i][j]);
printf("\n");
}
b[0][0]=a[0][0];
printf("%d\n",b[0][0]);
sum=a[0][0];
sum1=a[0][0];
for(i=1;i{
for(j=0;j<=i;j++)
{
if(j==0)//第一列不用比较直接一次累加并一次保存
{
sum+=a[i][0];
b[i][0]=sum;
}
else
{
if(j==i)//处于对角线不用比较直接一次累加并一次保存
{
sum1+=a[i][i];
b[i][i]=sum1;
}
else
{
max=b[i-1][j-1]>b[i-1][j]?
b[i-1][j-1]:
b[i-1][j];//比较上面两个节点的大小
b[i][j]=max+a[i][j];
}
}
}
}
for(i=0;i<=count-1;i++)
{
for(j=0;j<=i;j++)
printf("%d",b[i][j]);
printf("\n");
}
maxz=0;
for(i=0;iif(b[count-1][i]>maxz)
{
maxz=b[count-1][i];
x=count-1;
y=i;
}
lu[x]=a[x][y];
while(x>0)//从下往上找出路径
{
cha=b[x][y]-a[x][y];
if(b[x-1][y-1]==cha)
{
lu[x-1]=a[x-1][y-1];
x=x-1;
y=y-1;
}
if(b[x-1][y]==cha)
{
lu[x-1]=a[x-1][y];
x=x-1;
}
}
printf("这条路的节点为\n");
for(i=0;i<=count-1;i++)
{
printf("%d",lu[i]);
}
printf("最大路径长为:
%d\n",maxz);
fclose(fp);
}