欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C/C++算法设计实验报告(源代码)

程序员文章站 2022-06-13 14:01:06
...

算法分析

请查看:
算法分析文章

程序源代码:

#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
#define N 200
#define MaxVertices 100 //假设包含100个顶点
#define MaxWeight 32767 //不邻接时为32767,但输出时用 "∞"
#define MAXV 10
#define INF 32767
using namespace std;
typedef struct{ //包含权的邻接矩阵的的定义
    int Vertices[MaxVertices];  //顶点信息的数组
    int Edge[MaxVertices][MaxVertices]; //边的权信息的数组
    int numV; //当前的顶点数
    int numE; //当前的边数
}AdjMatrix;


typedef struct array
{
	int *a;
	int n;
}Array;

void menu()//主菜单 
{	
//标题头 
	cout<<"				-----------------------------------------------------				"<<endl;
	cout<<"             					《算法设计与分析》实验"<<endl;
	cout<<"				-----------------------------------------------------"<<endl;
//选择菜单
	cout<<"				  1.算法分析基础——Fibonacci序列问题" <<endl;
	cout<<"				  2.分治法在数值问题中的应用——矩阵相乘问题 "<<endl;
	cout<<"				  3.减治法在数值问题中的应用——8枚硬币问题 "<<endl;
	cout<<"				  4.变治法在数值问题中的应用——堆排序问题 "<<endl;
	cout<<"				  5.动态规划法在图问题中的应用——全源最短路径问题 "<<endl;
	cout<<"				  99.退出本实验" <<endl;
	cout<<"				-----------------------------------------------------"<<endl;
	cout<<"				  请输入您所要执行的操作(1,2,3,4,5,99);"<<endl;
	
}

//Fibonacci算法实现阶段 
//Fibonacci数列
int Fi(int i)
{
	if(i<=1)
		return i;
	else
		return Fi(i-1)+Fi(i-2);
}

void Fn()
{
	int i=0,j=0;
	do
	{
		j=Fi(i);
		if(j>=0)
			printf("%d  ",j);
		++i;
	}while(j>=0);
	printf("\n计算机所能计算的最大整数是第%d个fibonacci整数。\n",i-1);
}

void Fib()
{ 
	int i=1,f[3]={0,1};
	printf("%d  \n",f[0]);
	do
	{	
		printf("%d  \n",f[1]);
		f[2]=f[1]+f[0];
		f[0]=f[1];
		f[1]=f[2];
		i++;
	}while(f[1]>=f[0]);
	printf("\n\t计算机所能表示的最大fibonacci整数是第%d个fibonacci整数。\n",i);
}

void fibonacci()
{
	double start;
	start=clock();
	Fib();
	printf("\t迭代所用时间是%lf \n\n",clock()-start);
	start=clock();
	Fn();
	printf("\t递归所用时间是%lf \n\n",clock()-start);
}



//矩阵相乘问题求解 
void PrintIn(Array A,Array B)
{
	int n=A.n;
	int i,j;
	printf("请输入A数据:\n");
	for(i=0;i<n;i++)
         for(j=0;j<n;j++)
			 cin>>A.a[i*n+j];
    printf("请输入B数据:\n");
	for(i=0;i<n;i++)
         for(j=0;j<n;j++)
           cin>>B.a[i*n+j];
}

void RandomIn(Array A,Array B)
{
	int n=A.n;
	srand((unsigned)time(NULL));
	int i,j;
	for(i=0;i<n;i++)
		for(j=0;j<n;j++)
			A.a[i*n+j]=rand()%10;
		
	for(i=0;i<n;i++)
	   for(j=0;j<n;j++)	  
		B.a[i*n+j]=rand()%10;
}
void PrintOut(Array A)
{  
	int n=A.n;
	int i,j;
	for(i=0;i<n;i++)
	   { for(j=0;j<n;j++)
		   cout<<A.a[i*n+j]<<' ';
		 printf("\n");	
	   }
}
void divide(Array d,Array d00,Array d01,Array d10,Array d11)  /*分割矩阵*/
{
	int n=d00.n;
   int i,j;
   for(i=0;i<n;i++)
   {
	   for(j=0;j<n;j++)
	   {
		   d00.a[n*i+j]=d.a[2*n*i+j];
		   d01.a[n*i+j]=d.a[2*n*i+n+j];
		   d10.a[n*i+j]=d.a[2*n*n+2*n*i+j];
		   d11.a[n*i+j]=d.a[2*n*n+2*n*i+n+j];
	   }
   }
}
Array merge(Array d00,Array d01,Array d10,Array d11)  
{
  int n=d00.n;
  int i,j;
  Array d;
  d.a=(int *)malloc(sizeof(int)* (4*n*n));
  for(i=0;i<n;i++)
   {
	   for(j=0;j<n;j++)
	   {
		   d.a[2*n*i+j]=d00.a[n*i+j];
		   d.a[2*n*i+n+j]=d01.a[n*i+j];
		   d.a[2*n*n+2*n*i+j]=d10.a[n*i+j];
		   d.a[2*n*n+2*n*i+n+j]=d11.a[n*i+j];
	   }
   }
  d.n=2*n;
  return d;
}
Array operator +(Array A,Array B)
{
	int n=A.n;
	Array C;
	C.a=(int *)malloc(sizeof(int)*(n*n));
	for(int i=0;i<n*n;i++)
		C.a[i]=A.a[i]+B.a[i];
	C.n=A.n;
	return C;
}
Array operator -(Array A,Array B)
{
	int n=A.n;
	Array C;
	C.a=(int *)malloc(sizeof(int)*(n*n));
	for(int i=0;i<n*n;i++)
		C.a[i]=A.a[i]-B.a[i];
	C.n=A.n;
	return C;
}
Array strassen(Array A,Array B) 
{  
  int n=A.n;
  Array C;
  C.a=(int *)malloc(sizeof(int)*(n*n));
  C.n=n;
  if(n==2)
  {
	int m1,m2,m3,m4,m5,m6,m7;
    m1=(A.a[0]+A.a[3])*(B.a[0]+B.a[3]);
    m2=(A.a[2]+A.a[3])*B.a[0];
    m3=A.a[0]*(B.a[1]-B.a[3]);
    m4=A.a[3]*(B.a[2]-B.a[0]);
    m5=(A.a[0]+A.a[1])*B.a[3];
    m6=(A.a[2]-A.a[0])*(B.a[0]+B.a[1]);
    m7=(A.a[1]-A.a[3])*(B.a[2]+B.a[3]);
    C.a[0]=m1+m4-m5+m7;
    C.a[1]=m3+m5;
    C.a[2]=m2+m4;
    C.a[3]=m1+m3-m2+m6;
    return C;
  }
else
  {
    n=n/2; 
	Array a00,a01,a10,a11;
    Array b00,b01,b10,b11; 
	Array c00,c01,c10,c11;
    Array s1,s2,s3,s4,s5,s6,s7; 
    a00.a=(int *)malloc(sizeof(int)* (n*n));
	a00.n=n;
    a01.a=(int *)malloc(sizeof(int)* (n*n));
	a01.n=n;
    a10.a=(int *)malloc(sizeof(int)* (n*n));
	a10.n=n;
    a11.a=(int *)malloc(sizeof(int)* (n*n));
	a11.n=n;
    b00.a=(int *)malloc(sizeof(int)* (n*n));
	b00.n=n;
    b01.a=(int *)malloc(sizeof(int)* (n*n));
	b01.n=n;
    b10.a=(int *)malloc(sizeof(int)* (n*n));
	b10.n=n;
    b11.a=(int *)malloc(sizeof(int)* (n*n));
	b11.n=n; 
    divide(A,a00,a01,a10,a11);
    divide(B,b00,b01,b10,b11); 
	s1=strassen(a00+a11,b00+b11);
	s2=strassen(a10+a11,b00);
    s3=strassen(a00,b01-b11);
    s5=strassen(a00+a01,b11);   
    s4=strassen(a11,b10-b00);    
    s6=strassen(a10-a00,b00+b01);
    s7=strassen(a01-a11,b10+b11); 
    c00=s1+s4-s5+s7;
    c01=s3+s5;
    c10=s2+s4;
    c11=s1+s3-s2+s6; 
    C=merge(c00,c01,c10,c11);
    return C;
  }
}
Array mul(Array A,Array B)  //普通的矩阵乘法计算
{
	int n=A.n;
	Array C;
	C.a=(int *)malloc(sizeof(int)*(n*n));
	C.n=n; 
    int i,j,k;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        {    
            C.a[i*n+j]=0;
            for(k=0;k<n;k++)
            C.a[i*n+j]=C.a[i*n+j]+A.a[i*n+k]*B.a[k*n+j];
        }
	return C;
}
void matrix()
{   
	int n;
	char ch;
	Array A,B,C;
	
	printf("\t\t计算M1×M2 的乘积\n");
	printf("\t\t输入矩阵阶数n:");
	scanf("%d",&n); 
    A.a=(int *)malloc(sizeof(int)* (n*n));
	A.n=n;
    B.a=(int *)malloc(sizeof(int)* (n*n));
	B.n=n;
    C.a=(int *)malloc(sizeof(int)* (n*n));
    C.n=n; 
    printf("\t\t---1 手动输入---\n");
    printf("\t\t---2 随机生成---\n");
    printf("\t\t请选择\n\n");
    ch=getch();
	switch(ch)
	   {
	   case '1':
	           printf("手动输入\n");
			   PrintIn(A,B);			   
			   printf("\n");
			   break;
	   case '2':
		           printf("自动生成\n");
				   
				   RandomIn(A,B);				   
				   			   
				   break;
	   default:
				printf("按键错误\n");break;
	   }
	   printf("结果数组A中数据为:\n");
	   PrintOut(A);
	   printf("结果数组B中数据为:\n");
	   PrintOut(B);
	   cout<<endl; 
	   do
	   {
		   double start, finish,duration; 
		   printf("\n---1 用BF方法---\n");
		   printf("---2 用DAC方法---\n");
		   printf("---3   退出 ---\n");
		   printf("\n请选择:");
		   ch=getch();
		   switch(ch)
		   {
		   case '1': 
			   start = clock();
			   C=mul(A,B);
			   finish = clock();
			   duration = (double)(finish - start); 
			   printf("\n用BF方法得出的结果\n");
			   PrintOut(C);
			   printf( "用BF方法计算矩阵所花费的时间是:%f ms\n", duration );
			   printf("\n");break;
		   case '2':
 			   start = clock();
			   C=strassen(A,B);
			   finish = clock();
			   duration = (double)(finish - start); 
			   printf("用DAC方法得出的结果\n");
			   PrintOut(C);
			   printf( "DAC方法计算矩阵所花费的时间是:%f ms\n", duration );
			   printf("\n");break;
		   case '3':
       			exit(0);
		   default:
			   printf("按键错误\n");
	   }
		   printf("\n 你想用另外一种方法吗?请输入(Y/N)?:");
		   do
		   {
			   ch=getchar();
		   }while(ch!='Y'&&ch!='y'&&ch!='N'&&ch!='n');
	   }while(ch=='Y'||ch=='y');
}



//硬币算法实现阶段
void print(int jia, int zhen, int i)
{
	if(jia > zhen)
	{
		cout<<"位置在:"<<(i + 1)<<"是假币!"<<"且偏重!";
	}
	else {
		cout<<"位置在:"<<(i + 1)<<"是假币!"<<"且偏轻!";
	}
}
void compare(int a, int b,int real, int index1,int index2)
{
	if(a == real)
	{
		print(b,real,index2);
	}
	else
	{
		print(a, real,index1);
	}
}
void eightcoin(int arr[])
{
	//1. 取数组中的前6个元素分为两组进行比较abc,def
	//会有a+b+c > d+e+f | a+b+c == d+e+f | a+b+c < d+e+f 三种情况
	int abc = arr[0] + arr[1] + arr[2];
	int def = arr[3] + arr[4] + arr[5];
	int a = arr[0];
	int b = arr[1];
	int c = arr[2];
	int d = arr[3];
	int e = arr[4];
	int f = arr[5];
	int g = arr[6];
	int h = arr[7];
	if(abc > def)		//6枚硬币必有一枚假币,g,h为真币
	{
		if((a + e) > (d + b))	//去掉c,f,且b,e互换后,没有引起天平变化,说明假币必然是a,d中的一个
		{
			compare(a, d, g,1,3);
			
		}
		else if((a + e) == (d + b))
		{
			compare(c,f,g,2,5);
		}
		else
		{
			compare(b,e,g,1,4);
		}
	}
	else if(abc == def)	//假币在g,h之中,最好状态
	{
		
		if(g == a)
		{
			print(h,g,7);
		} 
		else
		{
			print(g,h, 6);
		}
 
	}
	else				//abc < def 这两组存在一枚假币,g,h为真币
	{
		if((a + e) > (d + b))
		{
			compare(b,e,g,1,4);
		}
		else if((a + e) == (d + b))
		{
			compare(c,f,g,2,5);
		}
		else
		{
			compare(a, d, g,1,3);
		}
	}
 
}
void yingbi()//主函数 
{
	cout<<"实验3"<<endl; 
	int i = 0;
	int arr[8];
	//这里输入a、b、c、d、e、f、g、h的重量
	cout<<"请输入八枚硬币:"<<endl;
	for(i; i < 8; i++)
	{
		cin>>arr[i];
	}
	eightcoin(arr);
	
}

//堆排序
void in(int h[N],int n)
{
	int i;
	printf("手动输入要排序的数:");
	for(i=1;i<=n;i++)
		scanf("%d",&h[i]);
}
void random(int h[N],int n)
{
	int i;
    for(i=1;i<=n;i++)
		h[i]=rand();
    printf("随机产生要排序的数如下所示:\n");
    for(i=1;i<=n;i++)
        printf("%d\t",h[i]);
	printf("\n\n");
}
//自底向上构造一个堆
void HeapBottomUp(int h[],int n)
{
	int heap,i,k,v,j; 
	for(i=(n/2);i>0;i--)
	{
		k=i;
	    v=h[k];
        heap=0;
	    while((heap==0)&&(2*k<=n))
		{
			j=2*k;
			if(j<n)
			{
				if(h[j]<h[j+1])
		        j=j+1;
			}
			if(v>h[j])
				heap=1;
			else
			{
				h[k]=h[j];
				k=j;
				h[k]=v;
			}
		}
	}
}
void HEAP()
{
	int h[N]={0},i,n,elem,m;
    double start, finish;
    char ch=' ';
    printf("\n\t\t输入要排序的数的规模:");
	scanf("%d",&n);
    printf("\n---1 手动输入---\n");
    printf("---2 自动生成---\n");
    printf("请选择:");
	do{
		ch=getch();
		if(ch=='1')
			in(h,n);
		if(ch=='2')
			random(h,n);
		else
			printf("\n输入出错,请重输:");
	}while(ch!='1'&&ch!='2');
	start=clock();
	m=n;
	while(m>1)
	{
	     HeapBottomUp(h,m);
	     //for(i=1;i<=n;i++)
			 //printf("%d\t\t",h[i]);
		 //printf("\n");
		 //根键(最大)与堆中最后一个键交换
         elem=h[1];
	     h[1]=h[m];
	     h[m]=elem;
         m=m-1;//堆的规模减一
         //for(i=1;i<=n;i++)
			 //printf("%d  ",h[i]);
         //printf("\n");
	}
	finish=clock();
	printf("\n输出排好的数组元素:\n");
    for(i=1;i<=n;i++)
	  printf("%d\t",h[i]);
	printf("\n输出算法执行的时间%f ",finish-start);
}


// 全源最短路径
void CreateGraph(AdjMatrix *G) //图的生成函数
{ 
    int n,e,vi,vj,w,i,j,choice,ret,k;
    FILE *fp;
    
	printf("请选择数据输入方式\n");
	printf("1.手动输入\n");
 	printf("2.自动输入\n"); 
    ret = scanf("%d",&choice); 
    
    while(ret != 1)
	{
		cout<<"您的输入有误,请重新输入!"<<endl;
		fflush(stdin);
		ret = scanf("%d",&choice);
	}
	
	if(choice == 2)
	{
  		n=rand()%10;
		  e=rand()%10;
		  //cout<<n<<"   "<<e<<endl;
   		G->numV=n;G->numE=e;
   		for(i=0;i<n;i++) //图的初始化
     	{
		    for(j=0;j<n;j++)
            { 
         	   if(i==j)
             	   G->Edge[i][j]=0;
          	  else 
           	     G->Edge[i][j]=32767;
            }
         } 
   		 for(i=0;i<n;i++)
   		 { 
       	 	for(i=0;i<G->numV;i++) //将顶点存入数组中
       		 { 
      		  //printf("请输入第%d个顶点的信息(整型):",i+1);  
     		 
     		   G->Vertices[i]=rand();
     		  // printf("第%d个顶点的信息(整型):%d",i+1,G->Vertices[i]);
      	 	 }
      	 } 
   		 printf("\n");

    	for(i=0;i<G->numE;i++)
   	    { 
       	   //printf("请输入边的信息i,j,w(以空格分隔):");
       	   vi=rand()%10;vj=rand()%10;w=rand()%10;
    		//printf("%d  %d  %d\n",vi,vj,w);
      	   //若为不带权值的图,则w输入1
           //若为带权值的图,则w输入对应权值

       	   G->Edge[vi][vj]=w;//①
      	   G->Edge[vj][vi]=w;//②
           //无向图具有对称性的规律,通过①②实现
           //有向图不具备此性质,所以只需要①
   		}
	}
	else
	{
		printf("请输入图的顶点数和边数(以空格分隔):");
  			scanf("%d%d",&n,&e);
   		G->numV=n;G->numE=e;
   		for(i=0;i<n;i++) //图的初始化
     	{
		    for(j=0;j<n;j++)
            { 
         	   if(i==j)
             	   G->Edge[i][j]=0;
          	  else 
           	     G->Edge[i][j]=32767;
            }
         } 
   		 for(i=0;i<n;i++)
   		 { 
       	 	for(i=0;i<G->numV;i++) //将顶点存入数组中
       		 { 
      		  printf("请输入第%d个顶点的信息(整型):",i+1);  
     		 // G->adjlist[i].vertex=getchar(); 
     		   scanf(" %d",&G->Vertices[i]);
      	 	 }
      	 } 
   		 printf("\n");

    	for(i=0;i<G->numE;i++)
   	    { 
       	   printf("请输入边的信息i,j,w(以空格分隔):");
     	   scanf("%d%d%d",&vi,&vj,&w); 
      	   //若为不带权值的图,则w输入1
           //若为带权值的图,则w输入对应权值

       	   G->Edge[vi][vj]=w;//①
      	   G->Edge[vj][vi]=w;//②
           //无向图具有对称性的规律,通过①②实现
           //有向图不具备此性质,所以只需要①
   		}
	}
}
void DispGraph(AdjMatrix G) //输出邻接矩阵的信息
{ 
    int i,j;
    printf("\n输出顶点的信息(整型):\n");
    for(i=0;i<G.numV;i++)
    {
       printf("%8d",G.Vertices[i]);
	}
	
	
    printf("\n\n\n输出邻接矩阵:\n");
    printf("\t");
    for(i=0;i<G.numV;i++)
        printf("%8d",G.Vertices[i]);

    for(i=0;i<G.numV;i++)
    { 
        printf("\n%8d",i);
        for(j=0;j<G.numV;j++)
        { 
        if(G.Edge[i][j]==32767) 
        //两点之间无连接时权值为默认的32767,但输出时为了方便输出 "∞"
            printf("%8s", "∞");
        else
            printf("%8d",G.Edge[i][j]);
        }
        printf("\n");   
    }
}
void Ppath(int path[][MaxVertices],int i,int j)
{
    int k;
    k=path[i][j];
    if (k==-1)
    {
        return;
    }

    Ppath(path,i,k);
    printf("%d->",k);
    Ppath(path,k,j);
}

void Dispath(int A[][MaxVertices],int path[][MaxVertices],int n)
{
    int i,j;
    for (i=0;i<n;i++)
    {
        for (j=0;j<n;j++)
        {
            if (A[i][j]==INF)
            {
                if (i!=j)
                {
                    printf("从%d到%d没有路径\n",i,j);
                }
            }
            else
            {
                printf("  从%d到%d的最短路径长度为:%d ",i,j,A[i][j]);
                printf("路径:%d->",i);

                Ppath(path,i,j);//两点i,j之间还有其他中继结点,则循环套用次函数
                printf("%d\n",j);
            }
        }
    }
}
void Floyd(AdjMatrix *G)
{
    int A[MaxVertices][MaxVertices],path[MaxVertices][MaxVertices];
    int i,j,k;
    //初始化
    for (i=0;i<G->numV;i++)
    {
        for (j=0;j<G->numV;j++)
        {
            A[i][j]=G->Edge[i][j];
            path[i][j]=-1;
        }
    }
//三重循环,floyd算法核心
    for (k=0;k<G->numV;k++)
    {
        for (i=0;i<G->numV;i++)
        {
            for (j=0;j<G->numV;j++)
            {
                if (A[i][j]>A[i][k]+A[k][j])
                {
                    A[i][j]=A[i][k]+A[k][j];
                    path[i][j]=k;
                }
            }
        }
    }
    Dispath(A,path,G->numV);//输出函数
}

void exit()
{
	cout<<"程序运行结束,窗口即将关闭!"<<endl;
	 system("pause");
}

void select ()//主菜单选择函数 
{
	AdjMatrix G;
	int n;
	cout<<"请输入:";
	cin>>n;
	//输入菜单数字判断 
	switch(n)
	{
		case 1:fibonacci();
		break;
		case 2:matrix();
		break;
		case 3:yingbi();
		break;
		case 4:HEAP(); 
		break;
		case 5:
				 CreateGraph(&G);
    			 Floyd(&G);
    			 DispGraph(G);
		break;
		case 99:exit();
		break;
		default :
			cout<<"输入错误"; 
			menu();
			select();
		
	}
}

int main(void)
{	
	int m =1;//控制菜单,始终进入 
	while (m == 1)
	{
			menu();
			select();
			cout<<endl; 
			cout<<"				是否继续?   继续请输入:1  不继续请输入:0 			"<<endl;
			cout<<endl; 
			cin>>m;
			system("cls");
	}
	
}


C/C++算法设计实验报告(源代码)