算法与编程总结报告
姓名: 陈凡超
学号: 11083136
专业: 信息对抗
时间:2012.6.14 - 6.26
————————————————————
目录
1.统计字母频率 (代码)
2.指示灯控制 (代码)
3.数字游戏 (代码)
4.判断点是否在三角形内 (代码+思路)
5.文件处理 - 通讯录 (代码+思路)
————————————————————
1.统计字母频率
代码:
#include<stdio.h>
int A_a( char a[] ){
}
void compile( char a[] , int b[] ){
}
int sort( int a[] , int b[] ){
}
int main( void ){
int est; printf("Input : 1 - 继续\n 0 - 结束\n"); while( scanf("%d",&est) , est==1 ){ char a[209]; int i; int output[26],output_n[26]; printf("请输入一个不包括空格的字母字符串,长度不大于200\n"); int i,max,x; int c[26]; for( i=0 ; i<26 ; i++ ) c[i]=a[i]; for( i=0 ; i<26 ; i++ ){ } int n,m; for( n=0,max=-1 ; n<26 ; n++ ) if( c[n]>max ) max=c[n] , m=n; b[i]=m , c[m]=-1; int i; for( i=0 ; i<26 ; i++ ) b[i]=0; /*b[]的初始化*/ for( i=0 ; a[i]!='\0' ; i++ ){ } b[ a[i]-97 ]++; /*大写转化成小写*/ int i; for( i=0 ; a[i]!='\0' ; i++ ){ } return 1; /*字符串正确返回1,错误返回0*/ if( a[i]<='Z'&&a[i]>='A' ) a[i]+=32; else{ } if( a[i]<'a'||a[i]>'z' ) return 0;
}
} scanf("%s",a); if( A_a( a )==1 ){ } else{ } sort( output , output_n ); printf("letter | times\n"); for( i=0 ; output[ output_n[i] ]!=0 ; i++ ){ } printf("\n"); printf("Input : 1 - 继续\n 0 - 结束\n"); printf(" %c | %d\n",output_n[i]+97,output[ output_n[i] ]); printf("字符串输入有误!\n"); printf("Input : 1 - 继续\n 0 - 结束\n"); continue; compile( a , output ); return 0;
————————————————————————————————————
2.指示灯控制
代码:
#include<stdio.h>
void first_light( int a[] , int N ){
}
void second_light( int a[] , int x , int N ){
}
int main ( void ){
int est; printf("Input : 1 - 继续\n 0 - 结束\n"); while( scanf("%d",&est) , est==1 ){ int N,i; int i,n; for( i=1 ; n=i*x,n<=N ; i++ ){ } if( a[n]==1 ) a[n]=0; else a[n]=1; /*light数组初始化*/ int i; for( i=0 ; i<=N ; i++ ) a[i]=1;
}
} int light[109]; int x; printf("请输入灯的数量 N<=100 \n"); scanf("%d",&N); first_light( light , N ); printf("Input : 操作人序号\n 0 - 结束\n"); while( scanf("%d",&x) , x!=0 ){ } for( i=1 ; i<=N ; i++ ){ } printf("\n\nInput : 1 - 继续\n 0 - 结束\n"); if( light[i]==1 ) printf("第 %d 盏灯是亮的\n",i); else printf("第 %d 盏灯是黑的\n",i); second_light( light , x , N ); return 0;
————————————————————————————————————
3.数字游戏
代码:
① 主程序
#include<stdio.h>
static int cacu[1000009],sushu[1009];
void sushu_1000(){
}x
void yueshu_b( int a[] , int c[] , int b ){
/*得到进制b的基本约数*/ int i=0,n=0,i_y=-1; while( b!=1 ){ if( b%sushu[i]==0 ){ /*从文件中读取1+1000的素数*/ FILE *fp; int i=0; fp=fopen("G:\\sushu.txt","r"); while( !feof( fp ) ){ } fclose( fp ); sushu[i-1]=EOF; fscanf(fp,"%d",&sushu[i]); i++;
} } } if( n==0 ){ } else c[ sushu[i] ]++; b/=sushu[i]; i_y++; c[ sushu[i] ]=1; a[ i_y ]=sushu[i]; n=1; else i++ , n=0; a[i_y+1]=EOF;
int last( int a[] , int c[] , int n ){
}
int main( void ){
int yueshu[50],yueshu_n[50],n,b; int i,N=0; int output; sushu_1000(); printf("请输入进制b和数n\n输入0时停止程序\n"); while( scanf("%d",&b) , b!=0 ){ N++; scanf("%d",&n); /*判断0的个数,计算方法用进制转化法*/ int x,xm,m,sum,min; int i,n_x; for( i=0,min=99999999 ; a[i]!=EOF ; i++ ){ } return min; min=99999999; x=a[i]; { } sum=sum-sum%c[ x ]; sum/=c[ x ]; if( sum<min ) min=sum; int i; for( i=1,sum=0 ; i*x<=n ; i++ ) cacu[i*x]=1 , sum++; for( xm=x*x,n_x=2 ; xm<=n ; xm*=x,n_x++ ){ } for( i=1 ; m=i*xm,m<=n ; i++ ){ } if( cacu[m]<n_x ) sum+=n_x-cacu[m] , cacu[m]=n_x;
} } yueshu_b( yueshu , yueshu_n , b ); output=last( yueshu , yueshu_n , n ); printf("Scenario #%d\n",N); printf("%d\n\n",output); printf("请输入数b和进制n\n输入0时停止程序\n");
②在文件中写入1-1000的所有素数程序
#include<stdio.h>
int main( void ){
}
FILE *fp; int i,n,est; int a[1009]={2}; fp=fopen("G:\\sushu.txt","w"); for( i=1,n=2; n<=1000 ; n++ ){ } a[i]=EOF; for( i=0 ; a[i]!=EOF ; i++ ) fprintf(fp,"%d ",a[i]); fclose(fp); int m; for( m=0,est=1 ; m<i ; m++ ){ } if( est==1 ){ } a[i]=n; i++; if( n%a[m]==0 ){ } est=0; break;
————————————————————————————————————
4.判断点是否在三角形内
代码:
#include<stdio.h>
static double a[2],b[2],c[2],d[2];
int estimate_line( int m , double d[]){
/*判断一个点在直线的哪边,顺时针方向的右边返回2,左边返回1,在边上返回3*/ double k,x,y;
double dx,dy; x=d[0]; switch( m ){ case 1 : dx=b[0]-c[0] , dy=b[1]-c[1]; if( dy==0 ){ } else{ } k=( dy )/( dx ); y=k*( x-b[0] )+b[1]; if( y<d[1] ) return 1; else{ } dx=a[0]-c[0] , dy=a[1]-c[1]; if( dy==0 ){ } else{ if( dx==0 ){ if( a[0]>d[0] ) return 2; else{ } if( a[0]==d[0] ) return 3; else return 1; if( a[1]>d[1] ) return 2; else{ } if( a[1]==d[1] ) return 3; else return 1; if( y==d[1] ) return 3; else return 2; if( dx==0 ){ } if( b[0]>d[0] ) return 2; else{ } if( b[0]==d[0] ) return 3; else return 1; if( b[1]>d[1] ) return 2; else{ } if( b[1]==d[1] ) return 3; else return 1; case 2 :
} } } } k=( dy )/( dx ); y=k*( x-a[0] )+a[1]; if( y<d[1] ) return 1; else{ } dx=a[0]-b[0] , dy=a[1]-b[1]; if( dy==0 ){ } else{ } k=( dy )/( dx ); y=k*( x-a[0] )+a[1]; if( y<d[1] ) return 1; else{ } if( y==d[1] ) return 3; else return 2; if( dx==0 ){ } if( a[0]>d[0] ) return 2; else{ } if( a[0]==d[0] ) return 3; else return 1; if( a[1]>d[1] ) return 2; else{ } if( a[1]==d[1] ) return 3; else return 1; if( y==d[1] ) return 3; else return 2; case 3 :
int estimate_abc(){
/*在三角形内返回-1,不在返回0,在边上返回1,2,3,在顶点上返回'a','b','c'*/ int est_r,est_d; int r[4]={0,0,0,0}; int i; est_r=estimate_line( 1 , a ); est_d=estimate_line( 1 , d ); if( est_d==3 ) r[1]=1;
} else{ } est_r=estimate_line( 2 , b ); est_d=estimate_line( 2 , d ); if( est_d==3 ) r[2]=1; else{ } est_r=estimate_line( 3 , c ); est_d=estimate_line( 3 , d ); if( est_d==3 ) r[3]=1; else{ } if( r[1]==0&&r[2]==0&&r[3]==0 ) return -1; else{ } if( r[1]==1 ){ } else{ } if( r[2]==1 ){ } else return 3; if( r[3]==1 ) return 'a'; else return 2; if( r[2]==0&&r[3]==0 ) return 1; else{ } if( r[2]==1 ) return 'c'; else return 'b'; if( est_r!=est_d ) return 0; if( est_r!=est_d ) return 0; if( est_r!=est_d ) return 0;
int estimate_right(){
/*能构成三角形返回1,不能构成三角形返回0*/ double dx_ab,dy_ab,dx_ac,dy_ac,dx_bc,dy_bc; double k_ab,k_ac; dx_ab=a[0]-b[0] , dy_ab=a[1]-b[1]; dx_ac=a[0]-c[0] , dy_ac=a[1]-c[1]; dx_bc=b[0]-c[0] , dy_bc=b[1]-c[1]; if( dx_ab==0&&dy_ab==0 ) return 0; else{ if( dx_ac==0&&dy_ac==0 ) return 0;
} } else{ } if( dx_bc==0&&dy_bc==0 ) return 0; k_ab=dy_ab/dx_ab; k_ac=dy_ac/dx_ac; if( k_ab*k_ab==k_ac*k_ac ) return 0; return 1;
int scanf_main(){
}
void printf_main( int est ){
switch( est ){ case 0 : printf("D点在三角形外\n"); break; printf("D点在三角形内但不在边上和顶点上\n"); break; printf("D点在三角形的bc边上\n"); break; printf("D点在三角形的ac边上\n"); break; printf("D点在三角形的ab边上\n"); break; /*能构成三角形返回1,不能构成三角形返回0*/ int i; int est; printf("请输入3个顶点的坐标(整数)\n"); printf("a点:\n"); for( i=0 ; i<2 ; i++ ) scanf("%lf",&a[i]); printf("b点:\n"); for( i=0 ; i<2 ; i++ ) scanf("%lf",&b[i]); printf("c点:\n"); for( i=0 ; i<2 ; i++ ) scanf("%lf",&c[i]); est=estimate_right(); if( est==0 ) return 0; printf("请输入D点的坐标(整数)\n"); for( i=0 ; i<2 ; i++ ) scanf("%lf",&d[i]); return 1; case -1 : case 1 : case 2 : case 3 : case 'a' :
} } printf("D点在三角形的a顶点上\n"); break; printf("D点在三角形的b顶点上\n"); break; printf("D点在三角形的c顶点上\n"); break; case 'b' : case 'c' :
int main( void ){
}
int est; int output; printf("Input : 1 - 开始\n 0 - 结束\n"); while( scanf("%d",&est) , est==1 ){ } int est_abc; est_abc=scanf_main(); if( est_abc==0 ){ } output=estimate_abc(); printf_main( output ); printf("\nInput : 1 - 开始\n 0 - 结束\n"); printf("Sorry,此3点无法构成三角形\n\n"); printf("Input : 1 - 开始\n 0 - 结束\n"); continue;
思路:
(1) 利用点与直线的关系判断点是否在三角形内
eg:
如果a和d在bc边的同一侧,b和d在ac边的同一侧,c和d在ab边的同一侧,
3个 条件满足时,d就在三角形内;
如果d在bc上,b和d在ac边的同一侧,c和d在ab边的同一侧,3个条件满足
时,d就在三角形的bc边上;
如果d在bc边上,也在ac边上。c和d在ab边的同一侧,3个
d就在三角形的c顶点上;
(2) 输入的3个顶点不在同一直线上且没有2点重合,这3点就能构成三角形
(3) 质心是中线的焦点,利用数学列出2条中线的方程组,得出质心x坐标和y坐标的通式,并 用c语言表达出来,最后计算两点之间的距离即可
(4) 此代码的(1)(2)(3)都用斜率k来解决c代码问题,当直线垂直于x坐标时单独考虑
条件满足 时,
————————————————————————————————————
5.文件处理 - 通讯录
代码:
#include<stdio.h>
static char data_name[1009][50],data_phone[1009][50],data_adrs[1009][50],data_d[10]; int x,n;
void help(){
}
int first(){
}
void last(){
int i; FILE *fp=fp=fopen("c:\\超凡通讯录\\data.txt","w"); fprintf(fp,"num. name phone adrs\n"); /*数据的导入与data_d[100]的初始化,并返回成员的数量*/ int n,i; FILE *fp; if( ( fp=fopen("c:\\超凡通讯录\\data.txt","r") )==0 ){ } for( n=0 ; n<4 ; n++ ) fscanf(fp,"%s",data_d); for( n=0 ; !feof( fp ) ; n++ ){ } fclose( fp ); return n-1; fscanf(fp,"%s %s %s %s",data_d,data_name[n],data_phone[n],data_adrs[n]); fp=fopen("c:\\超凡通讯录\\data.txt","w"); fprintf(fp,"num. name phone adrs\n"); return 0; int est; printf("----------------------------------------------------------------------\n"); printf(" 感情您对超凡通讯录的支持。\n"); printf(" 本通讯录数据默认存放在 c:\\超凡通讯录 文件夹中。\n"); printf(" 每次操作后程序将即时储存数据。\n"); printf(" 您可以储存1000个联系人。如需加大可在源代码中更改静态数组的大小。\n"); printf(" 制作 : 陈凡超 联系 : 手机 137xxxxxxxx QQ 542248022\n"); printf(" 如使用过程中遇到bug,请联系作者,谢谢。\n"); printf("----------------------------------------------------------------------\n"); printf(" 输入任意字符返回主菜单。\n"); scanf("%d",&est);
} for( i=0 ; i<n ; i++ ){ } fclose( fp ); if( i!=x ) fprintf(fp,"%-6d%-12s%-16s%s\n",i,data_name[i],data_phone[i],data_adrs[i]);
int menu_0(){
}
int menu_1(){
int est; printf("----------------------------------------------------------------------\n"); begin: int est; printf("-------------------------欢迎使用超凡通讯录---------------------------\n"); printf(" 1. 修改通讯录 \n"); printf(" 2. 查找 \n"); printf(" 3. 查看通讯录 \n"); printf(" 4. 帮助 \n"); printf(" 0. 退出 \n"); while( scanf("%d",&est) , est<0||est>4 ); printf("----------------------------------------------------------------------\n"); switch( est ){ } case 1 : menu_1(); printf("\n"); goto begin; menu_1_2(); printf("\n"); goto begin; menu_3(); printf("\n"); goto begin; help(); printf("\n"); goto begin; printf("\n"); return; begin: case 2 : case 3 : case 4 : case 0 :
} printf("修改通讯录 : \n"); printf(" 1. 添加联系人 \n"); printf(" 2. 修改联系人 \n"); printf(" 3. 删除所有联系人 \n"); printf(" 0. 返回主菜单 \n"); while( scanf("%d",&est) , est<0||est>3 ); printf("----------------------------------------------------------------------\n"); switch( est ){ } case 1 : menu_1_1(); printf("\n"); goto begin; menu_1_2(); printf("\n"); goto begin; menu_1_3(); printf("\n"); goto begin; printf("\n"); return; case 2 : case 3 : case 0 :
int menu_1_1(){
int i; x=9999; printf("----------------------------------------------------------------------\n"); while( 1 ){ } if( n==100 ){ } printf("请依次输入姓名,电话号码,地址\n"); scanf("%s %s %s",data_name[n],data_phone[n],data_adrs[n]); n++; printf("\n1. 继续 0. 返回\n"); last(); n=first(); while( scanf("%d",&i) , i<0||i>1 ); printf("----------------------------------------------------------------------\n"); if( i==0 ) return; printf("Sorry,成员已满.\n"); return;
}
int menu_1_2(){
int est,i; int input[50]; int num; x=9999; printf("----------------------------------------------------------------------\n"); printf("1. 输入姓名查找 2. 输入电话号码查找 3. 查看所有联系人 0. 返回上一级\n"); begin: while( scanf("%d",&est) , est<0||est>3 );
switch( est ){
case 1 :
printf("请输入姓名\n");
scanf("%s",input);
printf("----------------------------------------------------------------------\n"); printf("num. name phone adrs\n");
for( i=0 ; i<n ; i++ ){
if( compare_string( input , data_name[i] ) ){
printf("%-6d%-12s%-16s%s\n",i,data_name[i],data_phone[i],data_adrs[i]); }
}
break;
case 2 :
printf("请输入电话号码\n");
scanf("%s",input);
printf("----------------------------------------------------------------------\n"); printf("num. name phone adrs\n");
for( i=0 ; i<n ; i++ ){
if( compare_string( input , data_phone[i] ) ){
printf("%-6d%-12s%-16s%s\n",i,data_name[i],data_phone[i],data_adrs[i]); }
}
est=1;
break;
case 3 :
printf("----------------------------------------------------------------------\n"); printf("num. name phone adrs\n");
for( i=0 ; i<n ; i++ printf("%-6d%-12s%-16s%s\n",i,data_name[i],data_phone[i],data_adrs[i]);
est=1;
break;
case 0 : )
} printf("----------------------------------------------------------------------\n"); return; while( est==1 ){
改菜单\n");
printf("\n1. 继续 0. 返回上一级\n"); while( scanf("%d",&est) , est<0||est>1 ); if( est==0 ){ goto begin; } printf("请选择需修改成员的num\n"); scanf("%d",&num); printf("1. 修改 2.删除 0.返回修改菜单\n"); while( scanf("%d",&est) , est<0||est>2 ); switch( est ){ case 1 : printf("1.修改姓名 2.修改电话号码 3.修改地址 while( scanf("%d",&est) , est<0||est>3 ); printf("请输入修改内容\n"); switch( est ){ case 1 : scanf("%s",data_name[num]); break; case 2 : scanf("%s",data_phone[num]); break; case 3 : scanf("%s",data_adrs[num]); break; case 0 : printf("\n"); goto begin; } break; case 2 : x=num; break; case 3 : printf("\n"); goto begin; } last(); n=first(); 0.返回修
printf("修改成功\n");
printf("1. 继续修改 0. 修改完毕\n");
while( scanf("%d",&est) , est<0||est>1 );
if( est==0 ){
goto begin;
}
}
}
int menu_1_3(){
/*right!*/
FILE *fp;
fp=fopen("c:\\超凡通讯录\\data.txt","w");
fprintf(fp,"num. name phone adrs\n");
n=first();
printf("----------------------------------------------------------------------\n"); printf("删除所有联系人成功!\n");
printf("----------------------------------------------------------------------\n"); fclose( fp );
return;
}
int menu_3(){
int i;
printf("----------------------------------------------------------------------\n"); printf("num. name phone adrs\n");
for( i=0 ; i<n ; i++ printf("%-6d%-12s%-16s%s\n",i,data_name[i],data_phone[i],data_adrs[i]); printf("\n0. 返回主菜单\n");
while( scanf("%d",&i) , i!=0 );
printf("----------------------------------------------------------------------\n"); return;
}
int compare_string( char *a , char *b ){
/*比较两个字符串,一样返回1,不同返回0*/
int i;
for( i=0 ; *(a+i)!='\0'&&*(b+i)!='\0' ; i++ ){
if( *(a+i)!=*(b+i) ) return 0;
}
if( *(a+i)!='\0'||*(b+i)!='\0' ) return 0;
return 1;
}
int main( void ){
n=first();
menu_0();
return 0; )
}
思路:
(1) 主函数仅包括从文件中读取数据,主菜单 两部分,别的均用代用函数实现
(2) 每个调用函数最后都返回上一层,防止用户重复操作导致调用函数不断循环
(3) 当用户操作后,立即刷新data文件,是用存于内存中的数据重新写文件,效率有些低,有待
改进 (4) 添加与修改成员比较简单,添加数据即可,并用n计算成员数量; 删除成员时,用x记录被删除成员的num,在重新刷新文件时不刷新这个成员的数据; 删除所有成员时,直接重新刷新文件,并不写入任何成员的数据
(5) 查找与修改成员中有部分相似,所以搜索采用同一调用函数
(6) 程序主要靠判断来进行流动,所以对判断部分做了循环优化,防止用户不小心输入无效字符
(7) 查找采用字符串对比,只设置了姓名与电话号码查找,个人感觉地址查找不多且暂时达不到相
似查找境界; 查找到的成员一一列出,用户根据num的输入来选择修稿成员 (8) 程序数据储存于 c:\超凡通讯录 文件夹中 ,因程序需要,第一次使用程序时需要在C盘根目录下创建名为“超凡通讯录”的文件夹,此须知已在附加的txt文件中说明
此题收获:
文件的部分操作进过此题训练以较熟练掌握,但深入的操作还未接触,须找机会近一步学习。
————————————————————————————————————
总结
写代码就好比说话,将数学思维等用C代码的形式表达出来,重要的是逻辑的严谨。
看再多的书也比不过经常写代码。
编程给我一种无法用言语表达的乐趣。