数据结构与算法分析算法分析的编程练习
Posted MenAngel
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法分析算法分析的编程练习相关的知识,希望对你有一定的参考价值。
数据结构和算法分析的编程习题。
(1)生成不重复的随机数,并且具有上界和下界。可以产生有序的,也可以产生无序的。
知识:
C编程语言不允许返回整个数组作为函数的参数。但是,您也可以返回一个指针,没有索引到一个数组中指定数组的名称。
例如:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<time.h> 4 5 int *getRandom(){ 6 static int r[10]; 7 int i; 8 srand((unsigned)time(NULL)); 9 for ( i = 0; i < 10; ++i){ 10 r[i] = rand()%100; 11 printf( "r[%d] = %d ", i, r[i]); 12 } 13 return r; 14 } 15 16 int main(){ 17 int *p; 18 int i; 19 p= getRandom(); 20 for (i=0;i<10;i++){ 21 printf( "*(p+%d):%d ",i, *(p+i)); 22 } 23 return 0; 24 }
运行结果:
错误运用的实例:
1)在上述第6行,定义数组时未用static int r[10],而是int r[10],错误运行的结果如下:
从结果看,第一个是正确的,其余的值都已经无效。原因是,虽然返回的依然是数组的头指针,但由于数组是在函数中定义的,在函数运行结束后就会收回内存空间,导致错误。所以必须用static int r[10];
2)若定义r数组时没有指定固定数值的大小,而是通过参数动态指定:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<time.h> 4 5 int *getRandom(int k,int h){ 6 //static int r[20-10];用这个不会出错,因为数组大小固定,编译时内存管理器能够预先分配好空间给静态数组 7 static int r[k-h];//这个是动态指定的,编译器无法预先分配内存空间,会出现错误 8 int i; 9 srand((unsigned)time(NULL)); 10 for ( i = 0; i < 10; ++i){ 11 r[i] = rand()%100; 12 printf( "r[%d] = %d ", i, r[i]); 13 } 14 return r; 15 } 16 17 int main(){ 18 int *p; 19 int i; 20 p= getRandom(20,10); 21 for (i=0;i<10;i++){ 22 printf( "*(p+%d):%d ",i, *(p+i)); 23 } 24 return 0; 25 }
则会出现下述错误:
解决方案:如果想要解决这个问题,则可以用malloc动态分配指定大小的内存空间:
#include<stdio.h> #include<stdlib.h> #include<time.h> int *getRandom(int k,int h){ //static int r[20-10];用这个不会出错,因为数组大小固定,编译时内存管理器能够预先分配好空间给静态数组 //static int r[k-h];//这个是动态指定的,编译器无法预先分配内存空间,会出现错误 int *r=(int *)malloc((k-h)*sizeof(int));//做这个例子时,文件后缀名是.cpp所以必须用强制类型转换 int i; srand((unsigned)time(NULL)); for ( i = 0; i < 10; ++i){ r[i] = rand()%100; printf( "r[%d] = %d ", i, r[i]); } return r; } int main(){ int *p; int i; p=getRandom(20,10); for (i=0;i<10;i++){ printf( "*(p+%d):%d ",i, *(p+i)); } return 0; }
本题答案:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<time.h> 4 5 //随机数生成器 6 //生成从i到j范围内的总数为total的整数,不能重复且无顺序 7 int *RandInt4(int total,int i,int j,int order){ 8 int *numberGroup=malloc(total*sizeof(int));//用于返回一个指定大小的数组 9 int tempory[j-i+1];//辅助产生随机数的数组。 10 int k;//用于循环遍历 11 int x;//接收产生的随机变量 12 srand(time(NULL)); 13 //初始化辅助数组 14 for(k=0;k<=j-i;k++){ 15 tempory[k]=0; 16 } 17 for(k=0;k<total;k++){ 18 L: x=rand()%(j-i+1)+i;//产生从i到j,包括i和j的随机数 19 if(tempory[x-i]==0){ 20 tempory[x-i]=1; 21 //当需要产生的数组是无序的则执行: 22 if(order==0){ 23 numberGroup[k]=x; 24 } 25 }else{ 26 goto L; 27 } 28 } 29 //当需要产生有序的随机数组时执行: 30 int w=0; 31 if(order!=0){ 32 for(k=0;k<j-i+1;k++){ 33 if(tempory[k]==1){ 34 numberGroup[w++]=k+i; 35 if(w>=total){ 36 break; 37 } 38 } 39 } 40 } 41 42 return numberGroup; 43 } 44 //默认无序,生成从i到j的total个整数 45 int *RandInt3(int total,int i,int j){ 46 if(total<=j-i+1){ 47 return RandInt4(total,i,j,0); 48 }else{ 49 printf("生成的数组过大。\\n"); 50 exit(0); 51 } 52 } 53 //默认无序,生成从i到j的随机整数j-i+1个 54 int *RandInt2(int i,int j){ 55 return RandInt4(j-i+1,i,j,0); 56 } 57 int main(){ 58 int *a; 59 int k; 60 int total; 61 printf("下面测试这个函数的功能:\\n"); 62 printf("产生20到39范围内有序的随机整数20个:\\n"); 63 total=39-20+1; 64 a=RandInt4(total,20,39,1); 65 for(k=0;k<total;k++){ 66 printf("%3d",a[k]); 67 } 68 printf("\\n产生15到34范围内无序的随机整数20个:\\n"); 69 free(a); 70 total=34-15+1; 71 a=RandInt3(total,15,34); 72 for(k=0;k<total;k++){ 73 printf("%3d",a[k]); 74 } 75 printf("\\n产生30~49范围内无序的随机整数:\\n"); 76 free(a); 77 a=RandInt2(30,49); 78 total=49-30+1; 79 for(k=0;k<total;k++){ 80 printf("%3d",a[k]); 81 } 82 printf("\\n产生30~49范围内有序的随机整数10个:\\n"); 83 free(a); 84 total=10; 85 a=RandInt4(total,30,49,1); 86 for(k=0;k<total;k++){ 87 printf("%3d",a[k]); 88 } 89 free(a); 90 return 0; 91 }
下面再给出另外两种算法:
1)算法1(更加低效):
生成随机数添入数组,当另外产生的随机数不同于所有的已经产生的随机数时才将新产生的随机数添入数组。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<stdlib.h> 4 5 int exsist(int temp,int *p,int length){ 6 int i; 7 for(i=0;i<length;i++){ 8 if(temp==p[i]){ 9 return 1; 10 } 11 } 12 return 0; 13 } 14 int *RandInt(int i,int j){ 15 int x,k; 16 int *p=malloc((j-i)*sizeof(int)); 17 srand(time(NULL)); 18 for(k=0;k<j-i;k++){ 19 L: x=rand()%(j-i)+i; 20 if(!exsist(x,p,k)){ 21 p[k]=x; 22 }else{ 23 goto L; 24 } 25 } 26 return p; 27 } 28 int main(){ 29 int *p=RandInt(0,20); 30 int i; 31 for(i=0;i<20-0;i++){ 32 printf("%2d ",p[i]); 33 } 34 return 0; 35 }
2)算法2:(更加高效):
在生成数到一个数组后,随机置换,打乱位置。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<time.h> 4 5 int RandNumber(int k){ 6 int x=rand()%k; 7 return x; 8 } 9 void swap(int *a,int *b){ 10 int temp=*b; 11 *b=*a; 12 *a=temp; 13 } 14 int *RandInt(int i,int j){ 15 int *p=malloc(sizeof(int)*(j-i)); 16 int k; 17 for(k=0;k<j-i;k++){ 18 p[k]=i+k; 19 } 20 for(k=0;k<j-i;k++){ 21 swap(&p[k],&p[RandNumber(j-i)]); 22 } 23 return p; 24 } 25 int main(){ 26 srand(time(NULL)); 27 int i; 28 int *p=RandInt(20,40); 29 for(i=0;i<20;i++){ 30 printf("%d ",p[i]); 31 } 32 return 0; 33 }
(2)给出一个有效的算法确定在一个排序的数组中是否存在整数i使得Ai=i:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<time.h> 4 5 int *RandInt4(int total,int i,int j,int order){ 6 int *numberGroup=malloc(total*sizeof(int));//用于返回一个指定大小的数组 7 int tempory[j-i+1];//辅助产生随机数的数组。 8 int k;//用于循环遍历 9 int x;//接收产生的随机变量 10 srand(time(NULL)); 11 //初始化辅助数组 12 for(k=0;k<=j-i;k++){ 13 tempory[k]=0; 14 } 15 for(k=0;k<total;k++){ 16 L: x=rand()%(j-i+1)+i;//产生从i到j,包括i和j的随机数 17 if(tempory[x-i]==0){ 18 tempory[x-i]=1; 19 //当需要产生的数组是无序的则执行: 20 if(order==0){ 21 numberGroup[k]=x; 22 } 23 }else{ 24 goto L; 25 } 26 } 27 //当需要产生有序的随机数组时执行: 28 int w=0; 29 if(order!=0){ 30 for(k=0;k<j-i+1;k++){ 31 if(tempory[k]==1){ 32 numberGroup[w++]=k+i; 33 if(w>=total){ 34 break; 35 } 36 } 37 } 38 } 39 return numberGroup; 40 } 41 void OldSearch(int *p,int length){ 42 int i; 43 for(i=0;i<length;i++){ 44 if(p[i]==i){ 45 printf("第%d个数是满足条件的,为%d\\n",i,p[i]); 46 } 47 } 48 } 49 void NewSearch(int *p,int low,int high){ 50 int i; 51 int mid=(low+high)/2; 52 if(high-low<2){ 53 if(low==p[low]){ 54 printf("第%d个数是满足条件的,为%d\\n",low,p[low]); 55 } 56 if(low!=high){ 57 if(high==p[high]){ 58 printf("第%d个数是满足条件的,为%d\\n",high,p[high]); 59 } 60 } 61 return; 62 } 63 if(mid<p[mid]){ 64 NewSearch(p,low,mid-1); 65 }else if(mid==p[mid]){ 66 NewSearch(p,low,mid-1); 67 printf("第%d个数满足条件的,为%d\\n",mid,p[mid]); 68 NewSearch(p,mid+1,high); 69 }else{ 70 NewSearch(p,mid+1,high); 71 } 72 } 73 int main(){ 74 int *p=RandInt4(30,-10,50,1); 75 int i; 76 for(i=0;i<30;i++){ 77 printf("第%2d个数是%2d",i,p[i]); 78 if((i+1)%5==0){ 79 printf("\\n"); 80 } 81 } 82 int n; 83 printf("请输入你想改变的位置:\\n"); 84 scanf("%d",&n); 85 p[n]=n; 86 printf("用效率低的算法OldSearch:\\n"); 87 OldSearch(p,30); 88 printf("用效率高的算法NewSearch:\\n"); 89 NewSearch(p,0,29); 90 printf("\\n"); 91 }
(3)给出有效的算法:
1)求最小子序列和:
2)求最大的正子序列和:
3)求最大子序列乘积:
1 #include<stdio.h> 2 3 int MinSubSequenceSum(int *a,int length){ 4 int thisSum,minSum,k; 5 thisSum=minSum=0; 6 for(k=0;k<length;k++){ 7 thisSum+=a[k]; 8 if(thisSum<minSum){ 9 minSum=thisSum; 10 }else if(thisSum>0){ 11 thisSum=0; 12 } 13 } 14 return minSum; 15 } 16 int MinZSubSequenceSum(int *a,int length){ 17 int thisSum,minZSum,k; 18 thisSum=minZSum=0; 19 for(k=0;k<length;k++){ 20 if(a[k]>0){ 21 thisSum+=a[k]; 22 }else{ 23 thisSum=0; 24 } 25 if(thisSum>minZSum){ 26 minZSum=thisSum; 27 } 28 } 29 return minZSum; 30 } 31 算法设计与分析练习题