目录
一、C语言程序设计部分
前言
我决定写一份关于安徽师范大学计算机专硕898相关的复习讲义。
主要内容包含知识点复习和书本例题以及课后习题的解答。
本人已经调剂上岸,898专业课得分114分,如需要898专业课辅导可以私信我
一、程序设计基础——从问题到程序设计(第2版的使用)
这本书是898考试的主要书籍,虽然在考纲上898要求考察C语言和数据结构,但是从历年的情况来看,主要的考察内容就在这一本书之中。
关于本书的第一到第三章部分由于过于基础,所有这里的笔记中不打算记录关于前三章的内容,同学们可以自行的对照书本进行学习。同时,我的笔记之中只是记录一些我认为可能的重点以及一些例题和课后习题编程题的答案。在复习的过程中同样不能够脱离课本这是重中之重的问题。
二、第四章程序的基本控制结构
2.1:基本知识点
1:输入输出(scanf,printf语句)
格式:
%x输出一个十六进制
%o输出一个八进制
%u输出一个十进制无符号整数
%c输出一个字符
%s输出一个字符串
%f输出小数形式(单精度)
%lf输出一个小数形式(双精度)
%e以指数形式输出一个单精度实数
2:基本运算
算数运算:+ - * / %;
关系运算符:< <= > >= == !=
逻辑运算符:&& || !
3:优先级结合性
() ! +,-(取正负) *,/,% +,- <,<=,>,>= ==,!= && ||
! 算数运算符 关系运算符 逻辑运算符 赋值运算
4:强制转化
由低到高强制转,由高到低自动转化。
char->short int->int->long int->float->double自动转,反过来就是强制转化。
2.2本章重点关注
欧几里得算法求最大公约数与最小公倍数。
九九乘法表的打印
素数判定的几种方法
break语句和continue的区别
哥德巴赫的猜想
2.3课后习题
课后习题我没有写的说明不重要,不需要进行过分的去理解。
1.数字加密
输入一个三位数,将其加密后输出。加密方法是对该数的每一位数字,将其加6后除以10取余数,作为该位上的新数字
再交换个位数字和百位数字。
#include <stdio.h>
int main(){
int num;//输入的三位数
int number[3];//存放每位上数字的数组
int i=0,temp;//i,数组的下标,temp临时变量
scanf("%d",&num);
if(num>99&&num<1000){//判断输入的数据是否符合范围要求
while(num!=0){
temp=num%10;
num/=10;
number[i++]=(temp+6)%10;//进行加密处理
}
}else{
printf("输入的数不符合要求\n");
}
for(i=0;i<3;i++)
printf("%d",number[i]);
return 0;
}
2.已知火车的出发时间和到达时间,计算并输出旅途时间。
假设用两个4位整数time1和time2分别表示火车出发和到达的时间,
其中前两位表示小时,后两位表示分钟。
#include <stdio.h>
int main(){
int time1,time2,t1y,t1m,t2y,t2m,count=0,ts,tm;
printf("请输入火车的出发时间和到达的时间:\n");
scanf("%d%d",&time1,&time2);
if(time1>time2){
printf("输入的时间不正确:\n");
return 0;
}
t1m=time1%100;
t1y=time1/100;
t2m=time2%100;
t2y=time2/100;
if(t1y>24||t1m>60||t2y>24||t2m>60){
printf("时间格式输入不正确\n");
return 0;
}
while(t1y!=t2y||t1m!=t2m){
count++;
t1m++;
if(t1m%60==0){
t1m=0;
t1y++;
}
}
tm=count%60;
ts=count/60;
printf("count=%d,%d小时%d分钟\n",count,ts,tm);
return 0;
}
3.输入两个整数m和n,输出m和n之间的所有素数
#include <stdio.h>
#include <math.h>
int Prim(int num){
//判定是否是素数
int k=sqrt(num),i;
for(i=2;i<=k;i++){
if(num%i==0){//不是素数
return 0;
}
}
return 1;//是素数
}
int main(){
int m,n,t,i;
printf("请输入区间[m,n]\n");
scanf("%d%d",&m,&n);
if(m>n){//需要保证m>n
t=m;
m=n;
n=t;
}
for(i=m;i<=n;i++){
if(Prim(i)==1) printf("%d ",i);
}
return 0;
}
4.求两位数中有多少没有重读数字的偶数(思考有没有其他的解决方式,以及改编题。)
#include <stdio.h>
int main(){
int i,a,b;//a,b代表两位数的十位和个位上的数字
for(i=10;i<100;i++){
b=i%10;
a=i/10;
if(a!=b)//不是重复的数字
printf("%d ",i);
}
return 0;
}
5.有一个皮球从高为H米的位置自由落下,触地后反弹到原高度的一半,再落下,再反弹,如此反复。
皮球在n次触地时在空中经过的总路程是多少米?第n次反弹的高度是多少米?
#include <stdio.h>
#include <math.h>
int main(){
float height, jump = 0, sumj = 0, sumd = 0, sum = 0;
int i,n;
printf("请输入初始高度和接地次数n\n");
scanf("%f%d",&height,&n);
for(i = 1; i <= n; i++){
sumd += height; // 第一次落地距离
jump = height/2;
sumj += jump; // 第一次弹起距离
height = jump; // 第一期弹起距离
sum = sumd + sumj;
}
printf("第%d次落地经过%f,第%d次反弹%f", sum-jump,jump);
return 0;
}
//第10次落地经过299.609375,第10次反弹0.097656
6.给定一个整数,将该整数中各个位上为偶数的数字去掉,再顺次排列,得到一个新的整数,
例如15236,输出153
#include <stdio.h>
#define N 100
int main(){
int a[N],tot=0,num,i;//tot统计数字长度
printf("请输入一个数字\n");
scanf("%d",&num);
while(num!=0){
if((num%10)%2!=0){
a[tot++]=num%10;
num/=10;
}else{
num/=10;
}
}
for(i=tot-1;i>=0;i--){
printf("%d",a[i]);
}
return 0;
}
三、第五章批量同类型数据的组织——数组
一维数组的定义
基类型 数组变量名[整型常量表达式]
eg: int a[10]
如下的定义方式是错误的
int n=10;
int a[n];//数组的长度不能是变量。
注:在目前的编辑上这种代码是可以运行通过的,但作为应试考试要按照书本为准。
一维数组的操作无非就是增删改查和数组逆置几种常见的考法。 基本上离不开数组的循环遍历操作。
本章注意点
哥德堡七桥问题
折半查找问题
折半查找的主要前提要求:数组是一个有序的数组要么增序要么降序。
让数组有序的排列函数有多种方式,后面我会单独写一章节进行记录。
eg:写一个程序要求每次输入一个数字,验证这个数字是否在数组之中如果存在那么返回数组的下标。(数组要求有序)
#include <stdio.h>
#define N 10
int a[N];
int ZheBanSearch(int a[],int num){
int low,high,mid,flag=0;//flag=0代表数组中不存在num
low=0;high=N;
while(low<high){//当low小与high执行while循环
mid=(low+high)/2;
if(a[mid]==num) {//此时中间的数字正好是num则返回
flag=1;
return mid;
}else if(a[mid]<num){//当a[mid]<num则low=mid+1
low=mid+1;
}else{
//此时是a[mid]>num high=mid-1
high=mid-1;
}
}
if(flag==0){
return 0;//说明数组中不存在值num
}
}
int main(){
int i,num;
printf("%d请输入一组有序的数组\n");
for(i=0;i<N;i++){
scanf("%d",&a[i]);
}
printf("请输入一个数字在数组中查找是否存在\n");
scanf("%d",&num);
int index=ZheBanSearch(a,num);
printf("%d\n",index);
return 0;
}
合并有序数组问题
设将两个有序的数组合并成一个有序的数组
改编关于有序合并的问题,由于在考纲中明确提出要考察数据结构的问题,所有我个人猜测
这个题目可以改编为两个有序链表的合并问题,这部分会在后面的数据结构部分提及。先期学习的时候要注意。
幻方数组:这个代码的程序并不复杂,主要在于幻方数组的规则一般不容易记住。这个了解即可。
课后习题
1判断一个整数中是否出现重复数字
改编题
1.1如果有重复的数字请将所有重复的数字组成一个新的数字eg:11122233333444 输出1234。
1.2如果在1.1的情况下只允许使用一个数组,如何完成代码? (这和下面的第三题是一个意思)
#include <stdio.h>
int fun1(int num){//
//判断一个整数中是否出现重复数字
int a[10]={0},t;//初始化0-9数字出现的次数都是0
while(num!=0){
t=num%10;
if(a[t]!=0){//没有出现重复数字
a[t]++;
}else{//出现了重复数字
return 0;
}
}
return 1;
}
int main(){
int num;
printf("请输入一个数字\n");
scanf("%d",&num);
int flag=fun1(num);
if(flag==1){
printf("%d中没有重复的数字\n",num);
}
return 0;
}
2在一维数组中删除所有值为x的元素。(如果只可以定义一个数组呢?)
#include <stdio.h>
#define N 50
int main(){
int a[N],n,i,num,tot=0,b[N];
printf("请输入数组的长度n\n");
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
printf("请输入要删除的值\n");
scanf("%d",&num);
for(i=0;i<n;i++){
if(a[i]!=num)
b[tot++]=a[i];
}
for(i=0;i<tot;i++){
printf("%d ",b[i]);
}
return 0;
}
3删除一维数组中值相同的多余元素,即值相同的元素只保留一个。
#include <stdio.h>
#define N 50
int a[N];
int fun(int num,int len){
int i;
if(len==0) return 0;//没有出现过
else{
for(i=0;i<len;i++){
//检测值num有没有在前len个数中出现过
if(a[i]==num) return 1;//出现过
}
}
return 0;
}
int main(){
int n,i,j,tot=0;
printf("请输入数组的长度n\n");
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(i=0;i<n;i++){
if(fun(a[i],tot)==0){
a[tot++]=a[i];
}
}
for(i=0;i<tot;i++){
printf("%d ",a[i]);
}
return 0;
}
4将一维整型数组调整为左右两部分,左边所有元素均为奇数,右边所有元素均为偶数。(考虑如果只有一个数组呢)
#include <stdio.h>
#define N 10
int main(){
int a[N]={1,2,3,4,5,6,7,8,9,10};
int i,j,t;
for(i=0;i<N;i++){
if(a[i]%2==0)//偶数
{
for(j=i;j<N;j++){
if(a[j]%2==1)//寻找奇数
{
t=a[j];
a[j]=a[i];
a[i]=t;
}
}
}
}
for(i=0;i<N;i++){
printf("%d ",a[i]);
}
return 0;
}
//这是两个数组的情况,复杂度为n
#include <stdio.h>
void fun(int a[],int b[],int n){
int i,k=0,j=n-1;
for(i=0;i<n;i++){
if(a[i]%2==1)//奇数
{
b[k++]=a[i];
}else{
//偶数
b[j--]=a[i];
}
}
}
int main(){
int a[10]={2,3,12,14,13,18,19,4,7,6};
int b[10]={0};
fun(a,b,10);
for(int i=0;i<10;i++)
printf("%5d",b[i]);
return 0;
}
5在一个整型数组上,如果下标为i的数组元素大于相邻的数组元素,或者小于相邻的数组元素,
则称该元素为一个极值点。请输出数组中所有的极值点的下标
#include <stdio.h>
#define N 100
int main(){
int n,i;
printf("请输入数组的长度\n");
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(i=1;i<n-1;i++){
if((a[i]>a[i-1]&&a[i]>a[i+1])||(a[i]<a[i-1]&&a[i]<a[i+1])){
printf("%d ",i);
}
}
return 0;
}
6大整数加法
#include <stdio.h>
#define N 25
#define M 20
int main(){
int i,j,k,len1,len2,lens;//len1,len2代表两个大整数的长度
int a[N]={0},b[N]={0};
scanf("%d",&len1);//第一个数的长度
for(i=len1-1;i>=0;i--){
scanf("%d",&a[i]);
}
scanf("%d",&len2);//第二个数的长度
for(i=len2-1;i>=0;i--){
scanf("%d",&b[i]);
}
//相加
lens=len1>len2?len1:len2;
for(i=0;i<lens;i++){
k=a[i]+b[i];
if(k>=10){
a[i]=k%10;
a[i+1]+=k/10;
}else{
a[i]=k;
}
}
for(i=lens-1;i>=0;i--){
printf("%d",a[i]);
}
return 0;
}
7从考试成绩中划出及格线。期末考试评卷完成后,老师需要划出及格线,要求如下
(1)及格线是10的倍数
(2)保证至少有60%的学生及格
(3)如果所有的学生都高于60分,则及格线为60分
#include <stdio.h>
#define N 100
int AllStudentS(int a[],int num){//检测是否所有的学生成绩大于60
int tot=0,i;//tot统计成绩大于60的学生人数
for(i=0;i<num;i++){
if(a[i]>=60) tot++;
}
if(tot==num) return 1;//所有人的成绩都是及格的。
else return 0;//并不是所有人的成绩都是及格的。
}
int fun(int a[],int num){
int n1=num/10*6;//保证及格人数是60%
//将数组进行降序排序
int i,j,k;
for(i=0;i<num;i++){
k=i;//选择排序法找出最大的一个值然后进行互换
for(j=i;j<num;j++){
if(a[k]<a[i]){
k=i;
}
}
if(k!=i){
int temp=a[i];
a[i]=a[k];
a[k]=temp;
}
}
int score=a[n1-1];//获取第n1个人的成绩
while(score%10!=0){//要保证及格线是10的倍数
score--;
}
return score;
}
int main(){
int num,score[N],i;
printf("请输入学生的个数\n");
scanf("%d",&num);
for(i=0;i<num;i++){
scanf("%d",&score[i]);
}
if(AllStudentS(score,num)==1){
printf("及格线为60分\n");
return 0;
}else{
printf("及格线是%d\n",fun(score,num));
}
return 0;
}
8矩阵转置运算(改编:矩阵乘法运算)
矩阵的转置
step1:for循环遍历列数
step2:嵌套for循环遍历行数
step3:a[i][j]=b[j][i];转置矩阵赋值操作
#include <stdio.h>
#define N 3
#define M 5
void ChangeRC(){//矩阵转置运算
int i,j,a[N][M];
printf("请输入矩阵\n");
for(i=0;i<N;i++){
for(j=0;j<M;j++){
scanf("%d",&a[i][j]);
}
}
printf("原矩阵输出如下:\n");
for(i=0;i<N;i++){
for(j=0;j<M;j++){
printf("%5d",a[i][j]);
}
printf("\n");
}
printf("转置矩阵结果输出如下\n");
for(i=0;i<M;i++){
for(j=0;j<N;j++){
printf("%5d",a[j][i]);
}
printf("\n");
}
}
void ABC(){//两矩阵相乘结果输出
int i,j,k=0;//i,j,k分别用来代表for循环的变量
int a[N][M],b[M][N],c[N][N]={0};//矩阵A乘以矩阵B赋值给矩阵C
printf("请输入数组A(3X5)\n");
for(i=0;i<N;i++){
for(j=0;j<M;j++){
scanf("%d",&a[i][j]);
}
}
printf("请输入数组B(5X3)\n");
for(i=0;i<M;i++){
for(j=0;j<N;j++){
scanf("%d",&b[i][j]);
}
}
//开始运算
for(i=0;i<N;i++){
for(j=0;j<N;j++){
for(k=0;k<M;k++){
c[i][j]+=a[i][k]*b[k][j];
}
}
}
for(i=0;i<N;i++){
for(j=0;j<N;j++){
printf("%d ",c[i][j]);
}
printf("\n");
}
}
int main(){
ChangeRC();
ABC();
return 0;
}
9求矩阵中的鞍点,aij是所在行的最大值同时又是所在列的最小值
#include <stdio.h>
#define N 5
int a[N][N];
void Input();//输入数组
int AnDian();//寻找安点
int main(){
printf("请输入五阶矩阵:\n");
Input();
int k=AnDian();
if(k==0){
printf("NO FIND!\n");
}
return 0;
}
void Input(){
int i,j;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
scanf("%d",&a[i][j]);
}
}
}
//寻找安点;
int AnDian(){
int i,j,k,r,c,value,count=0;
for(i=0;i<N;i++){//行
value=a[i][0];
r=i;c=0;
for(j=0;j<N;j++){//找出每行的最大值
if(value<a[i][j]){
value=a[i][j];
r=i;c=j;
}
}
for(k=0;k<N;k++){//遍历行最小值的所在列,判断是否依然是列的最小值
if(value>a[k][c]){
value=a[k][c];
r=k;
}
}
if(r==i){//如果最终行没有变化则说明行的最小值也是列的最小值。
printf("%d(%d,%d)\n",value,r+1,c+1);
count++;
}
}
if(count==0) return 0;
else return 1;
}
四、第六章程序的组装单元——函数
怎样定义函数:
C语言要求,在程序设计中用到的所有函数,必须先定义,后使用。定义函数应该包括以下几个内容。
1指定函数的名字,以便以后按名调用
2指定函数的类型,即函数返回值类型
3.指定函数的参数的名字和类型
4.指定函数应该完成什么操作,也就是函数是做什么的,即函数的功能,这是最重要的,在函数体中解决
本章重点关注:
本章的重点应该关注库函数的使用、随机数的运用、局部变量静态变量等问题。库函数主要不能忘记添加头文件这个事情。
随机数,存在考察编程题和填空的可能性。
随机数主要使用三个头文件和三个函数
如下例子所示
#include <stdio.h>//使用库函数scanf,printf和符号常量NULL
#include <stdlib.h>//使用库函数rand和srand
#include <time.h> //使用库函数time
#include <stdio.h>//使用库函数scanf,printf和符号常量NULL
#include <stdlib.h>//使用库函数rand和srand
#include <time.h> //使用库函数time
int main(){
int i,x;//i表示循环数,x作为随机变量值
srand(time(NULL));//初始化随机种子为当前系统时间
for(i=0;i<5;i++){
x=rand()%100;//产生0-99的随机数
printf("第%2d个随机数是%2d\n",i,x);
}
return 0;
}
静态变量只需要牢记静态变量一经分配内存空间,在程序运行的过程中就一直占有该内存空间。
本章的编程例题,欧几里得算法,随机数,三角形面积建议将代码写一遍。
本章课后习题
习题1:
输入一个日期,输出这天是该年的第几天
改编题输入两个日期,判断这两个日期之间隔离多少天。
step1:定义年月日三个变量,定义每年12个月份的天数放在一维数组中,然后输入三个变量的值。
step2: 用for循环将1-month-1个月的天数相加之后在加上month的day值。
step3:判断年份是否属于闰年,如果是闰年天数再加1。
#include <stdio.h>
#include <stdlib.h>
int main(){
int year,month,day;//变量名表示输入的年月日;
printf("请输入年月日的变量值:\n");//输入信息提示
scanf("%d%d%d",&year,&month,&day);
int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//数组下表1-12表示每个月的天数。
int sum=0,i;//sum变量记录日期是今年的第几天,变量i数组下标;
for(i=1;i<month;i++)
sum+=days[i];//对month-1个月的天数进行累加
sum+=day;//加上第month个月的日期天数
if((year%4==0&&year%100!=0)||(year%400==0))//判断是否是闰年
{
//是闰年天数需要加1
sum++;
}
printf("%d/%02d/%02d是一年中的第%d天\n",year,month,day,sum);
return 0;
}
习题2:判断给定的自然数是否为降序数。所谓降序数是指对于n=d1d2d3d4满足di>=d(i+1)
step1:输入一个数值,通过while循环将数值上的每一位放置在一位数组中。
step2:用for循环变量检测数组中的元素是否满足升序,满足就是降序数,不满足就不是降序数。
#include <stdio.h>//库函数使用scanf和printf
#define N 100 //定义数组固定长度
int Down(int num){//判断是否是降序数
int a[N],index=0;//数组存放数值每位上的值,index作为数组下标
while(num!=0){//值不为0时进入for循环
a[index++]=num%10;
num/=10;
}
int i;//for循环变量值
for(i=0;i<index-1;i++){//因为是逆序存储,所以判断是否是升序即可。
if(a[i]>a[i+1]) return 0;//不是升序,则原数值不是降序数,返回0
}
return 1;//是升序,则原数值是降序数,返回1
}
int main(){
int num,flag;//输出数值num,flag接收DOWN函数的返回结果。
scanf("%d",&num);
flag=Down(num);//接受函数Down的返回值
if(flag==1) printf("%d是降序数\n",num);
else printf("%d不是降序数\n",num);
return 0;
}
习题3:输入10个整数,求这10个整数中的最大值。
#include <stdio.h>//库函数的scanf和printf
#define N 10 //输入的10个整数
int main(){
int a[N],i,max;//存储数组的值,数组的下标,十个数中的最大值。
printf("请从键盘上输入10个元素:\n");//输入元素信息提示
for(i=0;i<N;i++){
scanf("%d",&a[i]);//从键盘上输入10个元素
}
max=a[0];
for(i=0;i<N;i++){
if(max<=a[i])//查找N个元素中的最大值
max=a[i];
}
printf("最大值元素为%d\n",max);
return 0;
}
习题4:输出1和100之间的所有素数。
改编:输出n-m之间的所有素数
#include <stdio.h>//库函数scanf和printf
#include <math.h>//使用库函数sqrt()
int Prim(int num){//素数判定函数
int k=sqrt(num),i;//取num的平方根
for(i=2;i<=k;i++){
if(num%i==0) return 0;//不是素数返回0
}
if(i>k) return 1;
}
int main(){
int i;
for(i=2;i<=100;i++){
if(Prim(i)==1) printf("%5d",i);
}
return 0;
}
请给小学生随机出10道加减法的练习题,要求:10以内的加减法,并且能批改。
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define N 10
int main(){
int num1,num2,num3;//num1,num2代表运算的数值,num3代表运算的符号
int i,x;//x作为输入的答案
srand(time(NULL));
for(i=0;i<N;i++){
num1=rand()%10;
num2=rand()%10;
num3=rand()%2;
if(num3==1){
printf("%d+%d=",num1,num2);
scanf("%d",&x);
if(x==num1+num2){
printf("回答正确\n");
}else{
printf("回答错误\n");
}
}else{
printf("%d-%d=",num1,num2);
scanf("%d",&x);
if(x==num1-num2){
printf("回答正确\n");
}else{
printf("回答错误\n");
}
}
}
return 0;
}
求x的y次幂,x为double型。不能使用C语言提供的标准函数库。
#include <stdio.h>
int main(){
double x,sum=1;
int i,y;
scanf("%lf%d",&x,&y);
for(i=0;i<y;i++){
sum=sum*y;
}
printf("sum=%lf\n",sum);
return 0;
}
打印杨辉三角形的前n行。
#include <stdio.h>
#define N 5
int main(){
int a[N][N]={0};
int i,j;
for(i=0;i<N;i++){
a[i][0]=1;//i行第一列为1
a[i][i]=1;//使对角线的元素值为1
}
for(i=2;i<N;i++){
//从第三行开始处理
for(j=1;j<i;j++){
a[i][j]=a[i-1][j-1]+a[i-1][j];
}
}
for(i=0;i<N;i++){
for(j=0;j<2*N-2*i;j++){
printf(" ");
}
for(j=0;j<=i;j++){
printf("%4d",a[i][j]);
}
printf("\n");
}
return 0;
}
五、第七章变量的间接访问——指针
课后习题
习题1:任意给定两个正整数a和n,计算a+aa+aaa+...的和
#include <stdio.h>
int main(){
int a,n;
printf("请输入a和n\n");
scanf("%d%d",&a,&n);
int i,sum=0,t=a;
for(i=1;i<=n;i++){
sum+=t;
t=t*10+a;
}
printf("sum=%d\n",sum);
return 0;
}
习题2:从键盘输入10个整数,求这10个整数的最大值和序号
#include <stdio.h>
#define N 10
int main(){
int a[N],i,maxi=0;
for(i=0;i<N;i++){
scanf("%d",&a[i]);
}
for(i=0;i<N;i++){
if(a[i]<=a[maxi]) maxi=i;
}
printf("最大值为:%d,下标为%d\n",a[maxi],maxi);
return 0;
}
习题3:把1,2,3,4,5,6,7,8,9组合成三个三位数,要求每个数字仅用一次,并且每个三位数均是完全平方数
#include <stdio.h>
#include <math.h>
#define N 25
int Jude(int num){//判断三个数是否都是不一样的数字
int a,b,c;
c=num%10;
b=num/10%10;
a=num/100;
if((a!=b)&&(b!=c)&&(c!=a))
return 1;
else
return 0;
}
int checkNum(int n1,int n2,int n3){
//求三个平方数是否不重复;
int a[10]={0};//1-9是否都存在
while(n1!=0){
int temp=n1%10;
n1/=10;
if(a[temp]==0) a[temp]=1;
else return 0;
}
while(n2!=0){
int temp=n2%10;
n2/=10;
if(a[temp]==0) a[temp]=1;
else return 0;
}
while(n3!=0){
int temp=n3%10;
n3/=10;
if(a[temp]==0) a[temp]=1;
else return 0;
}
return 1;
}
int main(){
int a[N]={0},tot=0,i;
for(i=11;i<=31;i++){
if(Jude(i*i)) a[tot++]=i*i;
}
for(i=0;i<tot-2;i++){
for(int j=i+1;j<tot;j++){
for(int k=j+1;k<tot;k++){
if(checkNum(a[i],a[j],a[k])==1){
printf("三位数是:%d %d %d\n",a[i],a[j],a[k]);
}
}
}
}
return 0;
}
习题4:哥德巴赫猜想:任意一个奇数(大于1)都可以分解为三个素数之和。随机产生10个大于1的奇数进行验证,
并给出每个奇数的分解结果。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
int Prim(int num){//判定素数函数
int k=sqrt(num);
int i;
for(i=2;i<=k;i++){
if(num%i==0) return 0;
}
if(i>k) return 1;
}
int GeDe(int num){
int i;
for(i=1;i<=num;i=i+2){
if(Prim(i)&&Prim(num-i))
return i;
}
return 0;
}
int main(){
int num,i,x;//输入一个素数
printf("请输入一个奇数\n");
scanf("%d",&num);
if(num%2==0){
printf("请输出奇数:\n");
}
for(i=1;i<=num/2;i=i+2){//这中方式会把所有的分解行驶输出
if(Prim(i)==1){
x=GeDe(num-i);
if(x){
printf("%d可以分解为三个素数是:%d %d %d\n",num,i,num-i-x,x);
}
}
}
return 0;
}
习题5:删除一维数组中值相同的多余元素,即值相同的元素只保留一个
step1:输入一个长度为nd的数组值集合
step2:开始for循环遍历去除多余的元素
step2.1:调用fun函数进行检测,检测当前值有没有在以前出现过
step2.2:如果出现过返回值为0,for循环继续调用fun函数如果没有出现过则在数组前不重复位置加入。继续执行for循环
#include <stdio.h>
#define N 50
int a[N];
int fun(int num,int len){
int i;
if(len==0) return 0;//没有出现过
else{
for(i=0;i<len;i++){
//检测值num有没有在前len个数中出现过
if(a[i]==num) return 1;//出现过
}
}
return 0;
}
int main(){
int n,i,j,tot=0;
printf("请输入数组的长度n\n");
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(i=0;i<n;i++){
if(fun(a[i],tot)==0){
a[tot++]=a[i];
}
}
for(i=0;i<tot;i++){
printf("%d ",a[i]);
}
return 0;
}
习题6:一维整型数组中可以有正整数、零和负整数,重新排列数组,使得负整数在前,然后是0,最后是正整数。
step1:对数组值进行选择排序,因为负数值小于0小于整数
#include <stdio.h>
#define N 10
void fun(int a[]){
int i,j,k;
for(i=0;i<N;i++){
k=i;
for(j=i;j<N;j++){
if(a[k]>a[j]) k=j;
}
if(k!=i){
int t=a[i];
a[i]=a[k];
a[k]=t;
}
}
}
int main(){
int a[N]={1,-2,3,-4,5,-6,7,8,0,10};
fun(a);
for(int i=0;i<N;i++){
printf("%d ",a[i]);
}
}
习题7:折半查找的主要前提要求:数组是一个有序的数组要么增序要么降序。
让数组有序的排列函数有多种方式,后面我会单独写一章节进行记录。
eg:写一个程序要求每次输入一个数字,验证这个数字是否在数组之中如果存在那么返回数组的下标。(数组要求有序)
#include <stdio.h>
#define N 10
int a[N];
int ZheBanSearch(int a[],int num){
int low,high,mid,flag=0;//flag=0代表数组中不存在num
low=0;high=N;
while(low<high){//当low小与high执行while循环
mid=(low+high)/2;
if(a[mid]==num) {//此时中间的数字正好是num则返回
flag=1;
return mid;
}else if(a[mid]<num){//当a[mid]<num则low=mid+1
low=mid+1;
}else{
//此时是a[mid]>num high=mid-1
high=mid-1;
}
}
if(flag==0){
return 0;//说明数组中不存在值num
}
}
int main(){
int i,num;
printf("%d请输入一组有序的数组\n");
for(i=0;i<N;i++){
scanf("%d",&a[i]);
}
printf("请输入一个数字在数组中查找是否存在\n");
scanf("%d",&num);
int index=ZheBanSearch(a,num);
printf("%d\n",index);
return 0;
}
习题8:设数组a[m]和b[n]均为升序序列,将这两个数组合并成一个升序序列c[n+m]
#include <stdio.h>
#define N 5
#define M 4
int main(){
int a[N]={1,3,5,7,9},b[M]={2,4,6,8},c[N+M];
int i=0,j=0,tot=0;
while(i<N&&j<M){
if(a[i]<b[j]){
c[tot++]=a[i++];
}else{
c[tot++]=b[j++];
}
}
while(i<N){
c[tot++]=a[i++];
}
while(j<M){
c[tot++]=b[j++];
}
for(i=0;i<N+M;i++){
printf("%d ",c[i]);
}
return 0;
}
习题9:从n个人中选出身高差值最小两个人作为礼仪(如果差值相同的话,选取其中最高的两个人)。要求输出两个礼仪的身高
step1:先将身高按照从大到小进行排序
step2:检查两两之间的差值,如果差值相同不更改(优先高的)
#include <stdio.h>
#define N 10
void SelectSort(int a[]){
int i,j,k,t;//作为for循环下标,t作为中间值的交换变量。
for(i=0;i<N;i++){
k=i;//假设a[k]是最大值
for(j=i;j<N;j++){
if(a[k]<a[j]) k=j;
}
if(k!=i){
t=a[i];
a[i]=a[k];
a[k]=t;
}
}
}
int main(){
int i,k;
int a[N]={165,181,186,176,172,178,175,165,170,173};
SelectSort(a);
k=0;
for(i=0;i<N-1;i++){
if(a[k]-a[k+1]>a[i]-a[i+1]) k=i;
}
printf("礼仪身高为%d和%d\n",a[k],a[k+1]);
return 0;
}
六、第八章字符数据的组织——字符串
本章重点关注
p158页例题8.1恺撒加密
p168例题8.3.1-字数统计
P169例题8.3.2字符串匹配
课后习题
1.交换两个字符串的值
#include <stdio.h>
#define N 100
int main(){
char str1[N],str2[N],str3[N];
char *s1=str1,*s2=str2,*s3=str3;
scanf("%s%s",s1,s2);
s3=s1;
s1=s2;
s2=s3;
printf("s1=%s s2=%s\n",s1,s2);
return 0;
}
2.对两个字符串进行比较。不能调用库函数
#include <stdio.h>
#define N 100
int main(){
char str1[N],str2[N];
scanf("%s%s",str1,str2);
int i;
for(i=0;i<N;i++){
if(str1[i]>str2[i]){
printf("%s大于%s",str1,str2);
break;
}else{
printf("%s大于%s",str1,str2);
break;
}
}
return 0;
}
3.将两个字符串首尾相接,形成一个新的字符串(不能调用库函数)
#include <stdio.h>
#define N 100
int main(){
char str1[N],str2[N];
scanf("%s%s",str1,str2);
int i=0,j=0;
while(str1[i]!='\0'){
i++;
}
for(j=0;str2[j]!='\0';j++){
str1[i++]=str2[j];
}
str1[i]='\0';
printf("%s\n",str1);
return 0;
}
4.字符串str1包括n个字符,请将此字符串从第i个字符串开始的全部字符复制给另一个字符串str2
#include <stdio.h>
#define N 100
int main(){
char str1[N],str2[N];
scanf("%s%s",str1,str2);
printf("从那个位置开始赋值:\n");
int i,j,n;
scanf("%d",&n);
while(str1[i]!='\0'){
i++;
}
for(j=n-1;str2[j]!='\0';j++){
str1[i++]=str2[j];
}
str1[i]='\0';
printf("%s\n",str1);
return 0;
}
5.统计一个英文句子中单词的个数,假设句子中只包含字母和空格,各单词之间用空格分隔,单词之间的空格可以有多个。
#include <stdio.h>
#define N 100
int main(){
char str[N];
int i=0,j,count=0;
gets(str);
while(str[i]!='\0'){
if((str[i]!=' '&&str[i+1]==' ')||(str[i]!=' '&&str[i+1]=='\0')){
count++;
}
i++;
}
printf("%s共有%d个单词\n",str,count);
return 0;
}
6.在一个英文句子中查找最长单词,假定句子只包含字母和空格,各单词之间用空格分隔,单词之间的空格可以有多个。
#include <stdio.h>
#include <string.h>
#define N 200
int main(){
char str1[N],str2[N]="\0",str3[N]="\0";
int i,j,k,len1,len2;
gets(str1);
i=0;j=0;k=0;
while(str1[i]!='\0'){
for(;(str1[i]>='a'&&str1[i]<='z')||(str1[i]>='A'&&str1[i]<='Z');i++){
str2[j++]=str1[i];
}
str2[j]='\0';
len1=strlen(str2);//得到目前单词的长度
len2=strlen(str3);
if(len1>len2){//找到了一个更长的单词
for(j=0;str2[j]!='\0';j++){
str3[k++]=str2[j];
}
str3[k]='\0';
k=0;
j=0;
i++;
}else{
//目前这个单词不是最长的
j=0;
k=0;
i++; //英文文献要向后移动
}
}
printf("%s中最长的单词是%s长度为%d\n",str1,str3,strlen(str3));
return 0;
}
7.判断一个大整数能否被11整除,可以通过以下方法;将该数的十进制表示从右端开始,每两位一组构成一个整数,然后将这些
数相加,判断其和能否被11整除。例如
将562843748分割成5,62,84,37,48,然后判断5+62+84+37+48能否被11整除。
#include <stdio.h>
#define N 100
int main(){
int a[N];//存放大整数
int i,j,k,t,n,sum=0;
printf("请输入大整数的长度:");
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&a[i]);//输入大整数
}
for(j=n-1;j>=1;j=j-2){
t=a[j-1]*10+a[j];
sum+=t;
}
if(sum%11==0){
for(k=0;k<n;k++){
printf("%d",a[k]);
}
printf("可以被11整除\n");
}else{
printf("不能被11整除\n");
}
return 0;
}
8.打字程序。在屏幕上输出一行英文字符串(带空格),然后提示用户原样输入这行字符,并给出用户输入的正确率。
#include <stdio.h>
#include <string.h>
#define N 100
int main(){
int count1=0,count2,n=0,i=0;
double a=0;
char str1[N][N],str2[N][N],ch='\0';
while(n<N&&ch!='\n'){
scanf("%s",str1[n]);
n++;
ch=getchar();
}
count1=n;
printf("请输入答案:\n");
n=0;
ch='\0';
while(n<N&&ch!='\n'){
scanf("%s",str2[n]);
n++;
ch=getchar();
}
count2=0;
for(i=0;i<count1;i++){
if(strcmp(str1[i],str2[i])==0){
count2++;
}
}
a=count2*1.0/count1;
printf("题目一共%d单词,你答对了%d个单词,正确率%6.2lf\n",count1,count2,a);
return 0;
}
七、第九章自定义数据类型
枚举
enum 枚举类型名{枚举元素表};
eg:
enum weekType {Sun,Mon,Tue,Wed,Thu,Fri,Sat};
枚举值分别代表0、1、2、3、4、5、6
课后习题
1.假设婚姻状况有以下三种:已婚(married)、离婚(divorced)和单身(single),定义枚举类型描述婚姻状况。
#include <stdio.h>
int main(){
enum Man {married=1,divorved,single} today;
int flag;
scanf("%d",&flag);
today=(enum Man)flag;
switch(today){
case married:
printf("已婚\n");break;
case divorved:
printf("离婚\n");break;
case single:
printf("单身\n");break;
}
return 0;
}
2.已知平面上两个点的坐标,以这两个点为左上角和右下角可以确定一个矩形,求这个矩形的周长。要求平面上的坐标和矩形都用结构体来表示
#include <stdio.h>
struct Angle{
int x1,y1,x2,y2;
int C;
}p;
int main(){
printf("请输入两个点:\n");
scanf("%d%d%d%d",&p.x1,&p.y1,&p.x2,&p.y2)
int length,width;
if(p.x1<p.x2){
width=p.x2-p.x1;
}
if(p.y1<p.y2){
length=p.y2-p.y1;
}
p.C=2*width+2*length;
printf("矩形周长为%d\n",p.C);
}
3.输入一个班级所有同学的期末成绩,并按照期末成绩降序排列
#include <stdio.h>
#define N 10
struct Student{
int score;//期末分数
int stuno;//学号
}stu[N];
int main(){
int i,j,k;
printf("请输入学生的学号和期末成绩:\n");
for(i=0;i<N;i++){
scanf("%d%d",stu[i].stuno,stu[i].score);
}
Student temp;
for(i=0;i<N;i++){
k=i;
for(j=i;j<N;j++){
if(stu[k].score<stu[j].score) k=j;
}
if(k!=i){
temp.score=stu[i].score;
temp.stuno=stu[i].stuno;
stu[i].score=stu[k].score;
stu[i].stuno=stu[k].stuno;
stu[k].score=temp.score;
stu[k].stuno=temp.stuno;
}
}
printf("成绩排名如下\n");
for(i=0;i<N;i++){
printf("%d\t%d\n",stu[i].stuno,stu[i].score);
}
return 0;
}
八、第十章再谈函数
本章重点
再谈函数(这一章节需要好好的研读一下,编程题的可能性很大)
引例10.1字符串的循环左移动
step1:n=字符串str的长度
step2:将字符串str的前i项逆置
step3:将字符串的后n-i逆置
step4:将字符串所有的字符逆置
#include <stdio.h>
#include <string.h>
#define N 50
void Reverse(char ch[],int low,int high);//执行逆置
void fun1(char ch[],int i);//执行循环左移动
void fun2(char ch[],int i);//执行右移动
int main(){
char str[N];
int i;
printf("请输入一个字符串:\n");
scanf("%s",str);
printf("请输入循环左移的位数\n");
scanf("%d",&i);
fun2(str,i);
printf("循环左移动之后的字符串为%s\n",str);
return 0;
}
void fun1(char ch[],int i){
int n=strlen(ch);
Reverse(ch,0,i-1);
Reverse(ch,i,n-1);
Reverse(ch,0,n-1);
}
void fun2(char ch[],int i){
int n=strlen(ch);
Reverse(ch,i,n-i-1);
Reverse(ch,0,i-1);
Reverse(ch,0,n-1);
}
void Reverse(char ch[],int low,int high){
//逆置区间是[low,high]
char temp;
int i,len=high-low+1;
for(i=0;i<len/2;i++){
temp=ch[low+i];
ch[low+i]=ch[high-i];
ch[high-i]=temp;
}
}
10.3.1实例 公共子序列
如果str既是str1的子串又是str2的子串,则str是str1和str2的公共子串
如下的过程是验证strB是否是strA的子串
即strA是主串
step1:初始化比较的起始位置i=0,j=0;
step2:length1=字符串strA的长度,length2=字符串strB的长度。
step3:当i<length1并且j<length2时重复执行下述操作
step3.1:如果strA[i]等于strB[j],则i++,j++;
step3.2:否则i++;
step4:如果j=length2,说明strB的字符串已经全部匹配
#include <stdio.h>
#include <string.h>
#define N 50
int ComString(char strA[],char strB[],char str[]);//strA和strB是主串,str是子串
int CmpString(char strA[],char str[]);//判断str[]是否是strA的子串
int main(){
char strA[N],strB[N],str[N];//主串和子串
printf("请输入主串1\n");
//scanf("%s",strA);//如果想输入带空格的字段,可以使用gets(strA)
gets(strA);
printf("请输入主串2\n");
//scanf("%s",strB);
gets(strB);
printf("请输入子串\n");
//scanf("%s",str);
gets(str);
if(ComString(strA,strB,str)==1){
printf("%s是公共子串\n",str);
}else{
printf("%s不是公共子串\n",str);
}
return 0;
}
int ComString(char strA[],char strB[],char str[]){
int flag=0;//匹配标志,初始化为不匹配。
flag=CmpString(strA,str);
if(flag==1)
return CmpString(strB,str);
else
return 0;
}
int CmpString(char strA[],char str[]){
int i=0,j=0;
int length1,length2;
length1=strlen(strA);
length2=strlen(str);
while(i<length1&&j<length2){
if(strA[i]==str[j]){
i++;j++;
}else{
i++;
}
}
if(j==length2){
return 1;//是子串
}else{
return 0;//不是子串
}
}
p210页汉诺塔问题
p211页折半查找问题:这中算法我已经在以前的章节中说明了,这里不再多说。
课后习题
1.求将三个数中最大值和最小值之间的差。要求使用嵌套函数实现
#include <stdio.h>
int main(){
int num1,num2,num3;
scanf("%d%d%d",&num1,&num2,&num3);
int max,min;
max=num1>num2?num1:num2;
min=num1>num2?num2:num1;
if(max<num3) max=num3;
if(min>num3) min=num3;
printf("%d",max-min);
return 0;
}
2.计算1!+2!+......+n!的值。要求用嵌套函数实现
#include <stdio.h>
int fun(int num){
int i,sum=1;
if(num==1) return num;
else{
for(i=1;i<=num;i++){
sum=sum*i;
}
return sum;
}
}
int main(){
int n,i;
scanf("%d",&n);
int sum=0;
for(i=1;i<=n;i++){
sum+=fun(i);
}
printf("sum=%d\n",sum);
return 0;
}
3.验证卡布列克运算。
#include<iostream>
#include <algorithm> //包含sort()函数,sort()函数--默认从小到大排序
using namespace std;
void fun(int n, int a[]); //将一个数字的各个数位从高到低依次存入一个数组中去
bool compare(int a, int b); //编写的sort函数的参数,以完成从大到小的排序
int maxNum(int a[]); //各个数位从大到小排列所组成的数
int minNum(int a[]); //各个数位从小到大排列所组成的数
int main() {
int n, a[4];
int max, min;
cin >> n;
while (1) {
fun(n, a);
max = maxNum(a);
min = minNum(a);
n = max - min;
cout << max << "-" << min << "=" << n << endl;
if (n == 6174)
break;
else
fun(n, a);
}
return 0;
}
void fun(int n,int a[]) {
int i = 3;
while (n > 0) {
a[i] = n % 10;
n = n / 10;
i--;
}
while (i > -1) { //处理位数小于4位的情形,不足4位的用0填充
a[i] = 0;
i--;
}
}
bool compare(int a, int b) {
return a > b;
}
int maxNum(int a[]) {
sort(a, a + 4, compare);
return a[0] * 1000 + a[1] * 100 + a[2] * 10 + a[3];
}
int minNum(int a[]) {
sort(a, a + 4);
return a[0] * 1000 + a[1] * 100 + a[2] * 10 + a[3];
}
4.将给定的字符串逆序输出。要求递归实现
#include <stdio.h>
#include <string.h>
#define N 100
int main(){
char str[N];
scanf("%s",str);
int i,len;
len=strlen(str);
for(i=len-1;i>=0;i--){
printf("%c",str[i]);
}
printf("\n");
return 0;
}
#include <stdio.h>
#include <string.h>
#define N 100
void fun(char str[],int len){
if(len!=-1){
printf("%c",str[len]);
fun(str,len-1);
}
}
int main(){
char str[N];
scanf("%s",str);
int len=strlen(str);
fun(str,len-1);
return 0;
}
5. 逆序对数的统计
#include <stdio.h>
#define N 3
int fun(int a[],int i){
if(i==N-1) return 0;
else{
int j,count=0;
for(j=i;j<N;j++){
if(a[i]>a[j]) count++;
}
return count+fun(a,i+1);
}
}
int main(){
//int a[N]={1,3,5,7,9,2,4,6,8,10};
int a[N]={2,3,1};
int count=0;//逆序数统计结果
count=fun(a,0);
printf("逆序数对数为%d\n",count);
return 0;
}
6.设无序序列T=(r1,r2,.....rn),T和第k小元素定义为T按照升序排列后在第k个位置上的元素。给定一个序列T和一个整数k,
请找出序列T的第k小元素。要求用递归函数实现。
这题要求使用递归,如果直接使用快排也是符合题意的
但是我个人的另一个想法是,递归k次每次去除当前数组中的最小值,当然这个方式右一定的问题。有兴趣的同学可以自己尝试一下。
#include <stdio.h>
#define N 10
void quick_sort(int a[], int left, int right){
int i,j,temp;
i=left;j=right;
if(i>=j) return;
temp=a[i];//将第一个值作为基准,保存在临时变量之中。
while(i<j){
while(i<j&&a[j]>=temp){//从右边开始寻找一个比基准更小的值
j--;
}
a[i]=a[j];//保存最小值到基准的位置上;
while(i<j&&a[i]<=temp){//从左边找一个比基准更大的值;
i++;
}
a[j]=a[i];//将比基准更大值放置在刚刚的右边比基准更小值的位置上。
}
a[i]=temp;//此时i==j将基准值放在i位置,此时a[i]前面的值都比a[i]小,a[i]后面的值都比a[i]大
//分成两部分继续进行快排
quick_sort(a,left,i-1);
quick_sort(a,i+1,right);
}
int main(){
int a[N]={1,3,5,7,9,2,4,6,8,10};
int k,i;
printf("请输入k值:\n");
scanf("%d",&k);
quick_sort(a,0,N-1);
printf("快排结果如下:\n");
for(i=0;i<N;i++){
printf("%d ",a[i]);
}
printf("\n");
printf("第%d小值是%d\n",k,a[k-1]);
return 0;
}
快速排序知识点:
描述:
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序 的平均时间复杂度为O(NlogN),是冒泡排序的一种改进版。
方法:快速排序主要采用“二分”的思想,步骤如下:
1) 设置两个变量i、j,排序开始的时候:i=0,j=n-1;
2)第一个数组值作为比较值,首先保存到temp中,即temp=A[0];
3)然后j-- ,向前搜索,找到小于temp后,因为s[i]的值保存在temp中,所以直接赋值,s[i]=s[j]
4)然后i++,向后搜索,找到大于temp后,因为s[j]的值保存在第2步的s[i]中,所以直接赋值,s[j]=s[i],然后j--,避免死循环
5)重复第3、4步,直到i=j,最后将temp值返回s[i]中
6) 然后采用“二分”的思想,以i为分界线,拆分成两个数组 s[0,i-1]、s[i+1,n-1]又开始排序
如下图,以数组 6 4 7 1 2为例:
九、第十一章再谈指针
十、第十二章再谈输入输出
十一、第十五章基本的算法设计技术
10、数据结构学习的前言(数据部分的考点知识点)
二、数据结构部分
前言
1、数据结构绪论
2、线性表
注意
898主要偏向与程序题的编写我个人认为数据结构部分关于线性表,链表,二叉树的先序中序后序层次广度深度,以及第七章的查找算法我认为是考试出题的一个方向。但是在链表和部分依然是最大可能性的出题,所以建议重点复习这一个章节。
顺序表的基本操作
顺序表的定义
#define N 50
typedef int ElemType;
typedef struct{
ElemType data[N];
int length;
}SqList;
初始化顺序表
void initSqList(int a[],SqList &sqlist,int n){
//初始化顺序表
int i;
for(i=0;i<n;i++){
sqlist.data[i]=a[i];
}
sqlist.length=n;
}
顺序表的插入操作
bool SqListInsert(SqList &sqlist,int i,ElemType e){
//待插入的顺序表,插入的位置,插入置的值
if(i<1||i>sqlist.length){
return false;//判断i的范围是否有效
}
if(sqlist.length>=N){
return false;//当前存储空间已经满了,不能插入
}
for(int j=sqlist.length;j>=i;j--){
sqlist.data[j]=sqlist.data[j-1];
}
sqlist.data[i-1]=e;//在i的位置e
sqlist.length++;
return true;
}
删除顺序表中的一个值
bool SqListDelete(SqList &sqlist,int i,Elemtype &e){
//删除sqlist顺序表中,第i位置上的元素,并且在删除之前将要删除的值赋值给e
if(i<1||i>sqlist.length){
return false;//判定i的范围是否有效
}
e=sqlist.data[i-1];//获取需要删除的值赋值给e;
for(int j=i;j<sqlist.length;j++){
sqlist.data[j-1]=sqlist.data[j];
}
sqlist.length--;
return false;
}
按值查找
int SqListLocateElem(SqList sqlist,ElemType e){
int i;
for(i=0;i<sqlist.length;i++){
if(sqlist.data[i]==e)
return i+1;//下标为i的元素值等于e,返回其位序i+1
}
return 0;
}
以上整体可以运行代码
#include <stdio.h>
#define N 50
typedef int ElemType;
typedef struct{
ElemType data[N];
int length;
}SqList;
void initSqList(int a[],SqList &sqlist,int n);
void PrintInfoList(SqList &sqlist);
bool SqListInsert(SqList &sqlist,int i,ElemType e);
bool SqListDelete(SqList &sqlist,int i,Elemtype &e);
int SqListLocateElem(SqList sqlist,ElemType e);
void initSqList(int a[],SqList &sqlist,int n){
//初始化顺序表
int i;
for(i=0;i<n;i++){
sqlist.data[i]=a[i];
}
sqlist.length=n;
}
void PrintInfoList(SqList &sqlist){
printf("顺序表的长度为%d\n",sqlist.length);
printf("顺序表的内容为:\n");
int i;
for(i=0;i<sqlist.length;i++){
printf("%d ",sqlist.data[i]);
}
printf("\n");
}
//顺序表的插入操作
bool SqListInsert(SqList &sqlist,int i,ElemType e){
//待插入的顺序表,插入的位置,插入置的值
if(i<1||i>sqlist.length){
return false;//判断i的范围是否有效
}
if(sqlist.length>=N){
return false;//当前存储空间已经满了,不能插入
}
for(int j=sqlist.length;j>=i;j--){
sqlist.data[j]=sqlist.data[j-1];
}
sqlist.data[i-1]=e;//在i的位置e
sqlist.length++;
return true;
}
//删除顺序表中的一个值
bool SqListDelete(SqList &sqlist,int i,Elemtype &e){
//删除sqlist顺序表中,第i位置上的元素,并且在删除之前将要删除的值赋值给e
if(i<1||i>sqlist.length){
return false;//判定i的范围是否有效
}
e=sqlist.data[i-1];//获取需要删除的值赋值给e;
for(int j=i;j<sqlist.length;j++){
sqlist.data[j-1]=sqlist.data[j];
}
sqlist.length--;
return false;
}
//按值查找
int SqListLocateElem(SqList sqlist,ElemType e){
int i;
for(i=0;i<sqlist.length;i++){
if(sqlist.data[i]==e)
return i+1;//下标为i的元素值等于e,返回其位序i+1
}
return 0;
}
int main(){
int a[5]={1,2,3,4,5};
SqList sqlist;
initSqList(a,sqlist,5);
PrintInfoList(sqlist);
//添加值演示
if(SqListInsert(sqlist,1,11)){
//在第一位置上加入一个值为11
PrintInfoList(sqlist);
}else{
printf("添加值失败\n");
}
return 0;
}
删除最小值的主要模块
bool Del_Min(SqList &L,ElemType &value){
if(L.length==0)
return false;
value=L.data[0];
int pos=0;//找到最小值的位置
for(int i=0;i<L.length;i++){
if(L.data[i]<value){
value=L.data[i];
pos=i;
}
}
L.data[pos]=L.data[L.length-1];
L.length--;//长度--
return true;
}
设计一个高效算法,将顺序表L的所有元素逆置,要求空间复杂度为O(1)
void Reverse(SqList &L){
ElemType temp;
for(int i=0;i<L.length/2;i++){
temp=L.data[i];
L.data[i]=L.data[L.length-i-1];//交换
L.data[L.length-i-1]=temp;
}
}
删除顺序表中所有值为x的值
用k记录顺序表L中等于x的元素个数,边扫描L边统计k,并将不等于x的元素前移k个位置,最后修改L的长度。
void del_x_all(SqList &L,ElemType x){
int k=0,i=0;
while(i<L.length){
if(L.data[i]==x)
k++;
else
L.data[i-k]=L.data[i];
i++;
}
L.length=L.length-k;
}
从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不相同
bool Delete_Same(SqList &L){
if(L.length==0)
return false;
int i,j;//i存储第一个不相同的元素
for(i=0,j=1;j<L.length;j++){
if(L.data[i]!=L.data[j])//查找下一个与上个元素不同的元素
L.data[++i]=L.data[j];//找到后,将元素前移
}
L.length=i+1;
return true;
}
线性表的链式表示
定义
typedef int ElemType;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
/*LNode:结点,*LinkList 指针指向struct*/
//1.建立没有头结点的链表
1.建立没有头结点的链表
bool InitNoHead(LinkList &L){
L=(LNode *)malloc(sizeof(LNode));
if(L=NULL){
printf("初始化内存分配失败\n");
return false;
}else{
return true;
}
}
2.建立有头结点的链表
bool InitHead(LinkList &L){
L=(LNode *)malloc(sizeof(LNode));
if(L=NULL){
printf("初始化内存分配失败\n");
return false;
}
L->next=NULL;
return true;
}
用头插法建立一个链表
简单来说,头插法是都加入的数值在前面比如输入顺序是1 2 3 4 5。则输出的结果是5 4 3 2 1
LinkList ListByHeadInsert(LinkList &L){
LNode *s;//建立一个结点
int x;
L=(LNode *)malloc(sizeof(LNode));
L->next=NULL;//初始化为空链表
scanf("%d",&x);
while(x!=9999){
s=(LNode *)malloc(sizeof(LNode));//申请一个结点的空间
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
用尾插法建立链表
尾插法比如输入的是1 2 3 4 5,输出的结果也是1 2 3 4 5
将所有的结点插在最末端
LinkList List_TailInsert(LinkList &L){
LNode *s,*r;//建立一个结点
int x;
L=(LNode *)malloc(sizeof(LNode));
L->next=NULL;//初始化为空链表
r=L;
scanf("%d",&x);
while(x!=9999){
s=(LNode *)malloc(sizeof(LNode));//申请一个结点的空间
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
按序号查找结点值
LNode *GetElem(LinkList L,int i){
int j=1;//计数
LNode *p=L->next;//将头结点赋值给p
if(i==0)//i==0代表查找就是头结点直接返回L
return L;
if(i<1) //若i无效则返回NULL
return NULL;
while(p&&j<i){
p=p->next;
j++;
}
return p;
}
按值查找结点
LNode *LocateElem(LinkList L,ElemType e){
LNode *p=L->next;
while(p!=NULL&&p->data!=e)
p=p->next;
return p;
}
插入结点操作
/*
p=GetElem(L,i-1);//查找插入位置的前驱结点
s->next=p->next;
p->next=s;
扩展:
对某一结点进行前插操作
将*s结点插到*p之前的主要代码
s->next=p->next;
p->next=s;
temp=p->data;
p->data=s->data;
s->data=temp;
*/
编程练习题
1.设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点
void Del_x_3(LinkList &L,ElemType x){
//递归实现在单链表L中删除值为x的结点
LNode *p;//p指向待删除结点
if(L==NULL)//递归出口
return;
if(L->data==x){//找到x值开始删除
p=L;
L=L->next;
free(p);
Del_x_3(L,x);
}else{
Del_x_3(L->next,x);
}
}
3、栈、队列和数组
4、串
5、树与二叉树
6、图
7、查找
8、排序
三、三大题型练习
1、填空题
2、阅读题
3、程序编程题
1.用递归把数组的n个数实现“倒序”。主函数输入n个数,用递归将其顺序颠倒,并输出
#include <stdio.h>
#include <math.h>
#define N 100
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void reverse(int a[],int low,int high)
{
if (low<high)
{
swap((a+low),(a+high)); //交换两个数 函数形式
reverse(a,low+ 1,high-1); //递归调用
}
}
int main(){
int a[N];
int n;
printf("需要输入的数(n个)\n");
scanf("%d",&n);
int i,j;
for(i=0;i<n;i++) scanf("%d",&a[i]);
reverse(a,0,n-1);
for(j=0;j<n;j++) printf("%d ",a[j]);
return 0;
}
2.男,女,小孩一共40人,共花了50元。男的花3元,女的花了2元,小孩花1元问男,女,小孩各多少人。
#include <stdio.h>
#include <math.h>
#define N 40
int main(){
int man,women,child;
for(man=0;man<=N;man++){
for(women=0;women<=N;women++){
for(child=0;child<=N;child++){
int person_sum=child+women+man;
int money_sum=child+women*2+man*3;
if(person_sum==40&&money_sum==50){
printf("男有%d人,女有%d人,小孩有%d人\n",man,women,child);
}
}
}
}
return 0;
}
3.10个负责打分的人,分值0-100,去掉最高分和最低分,余下8个分数平均分为最终分数 。
要求:
1 输入50个选手名字,与10个评委打分
2 按最终得分求名次,分一样则名次一样
3 最终结果输出在result.txt,包括姓名,10位评委的打分,最终得分和名次。且上下对齐。
最终得分相同的名次相同。
如四名选手 80 75 75 70 名次 1 2 2 4
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define N 5
struct student{
char name[20];
int score[10];//10个评委打分;
double endscore;//最后的分数
int rank;//成绩排名
}stu[N];
void reverse(){
int i,j,index;
struct student temp,k;
for(i=0;i<N;i++){
k=stu[i];index=i;
for(j=i+1;j<N;j++){
if(k.endscore<stu[j].endscore){
k=stu[j];
index=j;
}
}
if(i!=index){
temp=stu[i];
stu[i]=k;
stu[index]=temp;
}
}
}
void sortrank(){
int i,j,rank=0;
for(i=0;i<N;i++){
if(rank==0){
stu[i].rank=rank+1;
rank=rank+2;
}else{
if(stu[i].endscore==stu[i-1].endscore){
stu[i].rank=stu[i-1].rank;
rank++;
}else{
stu[i].rank=rank;
rank++;
}
}
}
}
int main(){
int i,j;
FILE *fp;
if((fp=fopen("result.txt","w+"))==NULL){
printf("cannot open the file:\n");
exit(0);
}
printf("请输入%d名人员信息:\n",N);
for(i=0;i<N;i++){
scanf("%s",stu[i].name);//输入姓名
int sum=0,max=0,min=101;
for(j=0;j<10;j++){//输入10名评委的打分
scanf("%d",&stu[i].score[j]);
sum+=stu[i].score[j];
if(max<=stu[i].score[j]) max=stu[i].score[j];
if(min>=stu[i].score[j]) min=stu[i].score[j];
}
sum=sum-min-max;
stu[i].endscore=sum/8.0;//最终得分
}
//按照最终得分进行排序
reverse();
//按照现有的排序进行排名
sortrank();
//写入文件
for(i=0;i<N;i++){
fprintf(fp,"%-s",stu[i].name);
for(j=0;j<10;j++)
fprintf(fp,"%-5d",stu[i].score[j]);
fprintf(fp,"%-5lf %-5d\n",stu[i].endscore,stu[i].rank);
}
//在屏幕上显示信息
for(i=0;i<N;i++){
printf("%-10s",stu[i].name);
for(j=0;j<10;j++)
printf("%-5d",stu[i].score[j]);
printf("%-5lf %-5d\n",stu[i].endscore,stu[i].rank);
}
fclose(fp);
return 0;
}
4.若两素数之差为2,则称该两素数为双胞胎数。求出[2,300]之内:
(1)所有素数并保存到prime.txt中
(2)有多少对双胞胎数
(3)最大的一对双胞胎数
#include <stdio.h>
#include <math.h>
int isprism(int n){
int i,j,k=sqrt(n);
for(i=2;i<=k;i++){
if(n%i==0) break;
}
if(i>k) return 1;
else return 0;
}
int main(){
int i,j,k=0,a[300]={0};
FILE *fp;
for(i=2;i<=300;i++){
if(isprism(i)) a[k++]=i;
}
if((fp=fopen("prime.txt","w+"))==NULL){
printf("cannot open the file:\n");
return 0;
}
//写入文件;
for(i=0;i<k;i++){
fprintf(fp,"%5d",a[i]);
}
int max1,max2,count=0;//记录最大双胞胎数以及计数有多少对;
for(i=0;i<k-1;i++){
if(a[i+1]-a[i]==2){
count++;
max1=a[i];
max2=a[i+1];
}
}
printf("一共有%d对双胞胎数,最大的双胞胎数是%d和%d\n",count,max1,max2);
fclose(fp);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define MAX(a,b) ((a)>(b)?(a):(b))
int isPrime(int num){
int i;
if(num<2) return 0;
for(i=2;i<=(num/2);i++){
if(num%i==0) return 0;
}
return 1;
}
int main(){
FILE *fp=fopen("prime2.txt","w+");
int sval=2,eval=300,cnt,cv,prime=3,max1,max2;
cnt=0;
cv=sval;
for(;cv<=eval;){
if(isPrime(cv)){
fprintf(fp,"%d\n",cv);
if(cv-prime==2){
printf("%d&%d\n",prime,cv);
max1=prime;
max2=cv;
cnt++;//数量+1;
}
prime=cv;
}
if(cv&1) cv+=2;
else cv++;
}
printf("总对数有:%d\n",cnt);
printf("最大的双胞胎数为:%d&%d",max1,max2);
fclose(fp);
return 0;
}
5.方程根求解问题
#include <stdio.h>
#include <math.h>
FILE *in=fopen("Coefficent.txt","r+");
FILE *out=fopen("result.txt","w+");
void deal(int a,int b,int c);
void deal(int a,int b,int c,double x);
void deal(int a,int b,int c,double x1,double x2);
int main(){
int a,b,c,a1,b1,c1;
double x1,x2,disc;
while((fscanf(in,"%d%d%d",&a1,&b1,&c1))!=EOF){
a=a1;b=b1;c=c1;
if((a!=0)&&(b!=0)){//ax*x+b*x+c或者a*x*x+b*x形式
disc=b*b-4*a*c;
if(disc>0){
x1=(-b-sqrt(disc))/(2*a);
x2=(-b+sqrt(disc))/(2*a);
deal(a,b,c,x1,x2);
}else if(disc==0){
x1=-b/(2*a);
deal(a,b,c,x1);
}else{
deal(a,b,c);
}
}else if((a==0)&&(b!=0)){
deal(a,b,c,-c/b);
}else if((a!=0)&&(b==0)){
if(a>0){
deal(a,b,c,sqrt(a/c),-sqrt(a/c));
}else{
deal(a,b,c);
}
}else if((a==0)&&(b==0)){
if(c==0){
deal(a,b,c);
}else{
deal(a,b,c);
}
}
}
fclose(in);
fclose(out);
return 0;
}
void deal(int a,int b,int c){
if(a==0&&b==0&&c==0){
printf("a=%d\tb=%d\tc=%d时方程无穷解\n",a,b,c);
}else
printf("a=%d\tb=%d\tc=%d时方程无实数解\n",a,b,c);
}
void deal(int a,int b,int c,double x){
printf("a=%d\tb=%d\tc=%d时方程具有单解x=%lf\n",a,b,c,x);
fprintf(out,"%d\t%d\t%d\t%lf\n",a,b,c,x);
}
void deal(int a,int b,int c,double x1,double x2){
printf("a=%d\tb=%d\tc=%d时方程具有双解x1=%lf\tx2=%lf\n",a,b,c,x1,x2);
fprintf(out,"%d\t%d\t%d\t%lf\t%lf\n",a,b,c,x1,x2);
}
6.已知总共有30名学生,每名学生有数学、语文、物理化学、英语5门功课
#include <stdio.h>
#include <math.h>
#define N 30
struct student{
int no;//学号
char name[20];//姓名
double score[5];//分数
double sum;//总分
int rank;//排名
}stu[N],temp,kem;
int main(){
int i,j,k;
double sum;
for(i=0;i<N;i++){
printf("请输入第%d个学生的信息:\n",i+1);
scanf("%d%s",&stu[i].no,stu[i].name);
sum=0;
for(j=0;j<5;j++){
scanf("%lf",&stu[i].score[j]);
sum+=stu[i].score[j];
}
stu[i].sum=sum;
}//信息初始化
//进行排序
for(i=0;i<N-1;i++){
kem=stu[i];k=i;
for(j=i+1;j<N;j++){
if(kem.sum<stu[j].sum){
k=j;
kem=stu[j];
}
}
temp=stu[i];
stu[i]=kem;
stu[k]=temp;
}//完成排序
//对学生进行名次确定.考虑并列的情况;
int rank=1;
for(i=0;i<N;i++){
if(i==0){
stu[i].rank=rank;
rank++;
}else{
if(stu[i].sum==stu[i-1].sum){
stu[i].rank=stu[i-1].rank;
rank++;
}else{
stu[i].rank=rank;
rank++;
}
}
}//完成名次确定
printf("按总分成绩排序信息:\n");
printf("学号\t姓名\t数学\t语文\t物理\t化学\t英语\t总分\t名次\n");
for(i=0;i<N;i++){
printf("%d\t%s\t",stu[i].no,stu[i].name);
for(j=0;j<5;j++){
printf("%6.3lf\t",stu[i].score[j]);
}
printf("%lf\t%d\n",stu[i].sum,stu[i].rank);
}
//关注前10名有单科成绩低于80分的情况
printf("前10名有单科成绩低于80分的情况\n");
printf("学号\t姓名\t数学\t语文\t物理\t化学\t英语\t总分\t名次\n");
for(i=0;stu[i].rank<=10;i++){
for(j=0;j<5;j++){
if(stu[i].score[j]<80) break;
}
if(j<5){
printf("%d\t%s\t",stu[i].no,stu[i].name);
for(j=0;j<5;j++){
printf("%6.3lf\t",stu[i].score[j]);
}
printf("%lf\t%d\n",stu[i].sum,stu[i].rank);
}
}
return 0;
}
2001 liu 85 85 85 76 100
2002 bao 90 90 90 90 90
2003 wang 100 100 100 100 70
2004 chen 70 100 80 90 60
2005 hu 100 50 100 90 100
2006 xu 70 90 90 90 90
2007 hua 10 10 10 10 10
2008 ma 20 20 20 20 20
2009 luo 30 30 30 30 30
2010 l1 40 40 40 40 40
2011 l2 50 50 50 50 50
2012 l3 60 60 60 60 60
2013 l4 70 70 70 70 70
2014 l5 80 80 80 80 80
2015 l6 90 90 90 90 90
2016 l7 40 40 40 40 40
2017 l8 50 50 50 50 50
2019 l9 60 60 60 60 60
2020 l10 70 70 70 70 70
2021 l11 80 80 80 80 80
2022 l12 90 90 90 90 90
2023 l13 40 40 40 40 40
2024 l14 50 50 50 50 50
2025 l15 60 60 60 60 60
2026 l41 70 70 70 70 70
2027 l51 80 80 80 80 80
2028 l61 90 90 90 90 90
2029 l52 80 80 80 80 80
2030 l62 90 90 90 90 90
2031 l62 90 90 90 90 90
7.组合数递归求解
#include <stdio.h>
#include <math.h>
int fun(int n,int k){
if(n==k||k==0) return 1;
else return fun(n-1,k-1)+fun(n-1,k);
}
int main(){
int n,k;
scanf("%d%d",&n,&k);
int s=fun(n,k);
printf("n=%d,k=%d时s=%d\n",n,k,s);
return 0;
}
8.递归函数练习题
#include <stdio.h>
#include <math.h>
#define N 20
int fun(int n){
if(n==1||n==2) return 1;
else return fun(n-1)+fun(n-2);
}
int main(){
int i,j;
FILE *fp=fopen("fab.txt","w+");
int s,sum=0;
for(i=1;i<N;i++){
s=fun(i);
sum+=s;
fprintf(fp,"%d\n",s);
}
printf("前20项之和%d\n",sum);
fclose(fp);
return 0;
}
9.按照题意求解车牌号
#include <stdio.h>
#include <math.h>
int main(){
int i,j,k,a[10]={0},t;
for(i=1000;;i++){
j=i;t=0;k=sqrt(i);
while(j!=0){
a[t++]=j%10;
j/=10;
}
if(a[0]==a[1]&&a[t-1]==a[t-2]&&k*k==i){
printf("车牌号是%d\n",i);
}
}
return 0;
}
10.日期问题
#include <stdio.h>
#include <math.h>
struct Date{
int y;
int m;
int d;
}time1;
int isYear(int year){
if(year<1000||year>9999){
return 0;//年的格式不对
}else if((year%4==0&&year%100!=0)||(year%400==0)){
return 1;//表示是闰年
}else return 2;//表示不是闰年
}
int checkMon(int month){
if(month<1||month>12) return 0;//月份的格式不对
else return 1;
}
int checkDay(){
int Tadays[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
if(isYear(time1.y)==1)//是闰年
Tadays[2]=29;
else if(isYear(time1.y)==2)//不是闰年
Tadays[2]=28;
if(time1.d<=Tadays[time1.m]) return 1;//天数正常
else return 0;//天数不正常
}
void EndDate(int days);
int main(){
printf("please input date\n");
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
time1.y=a;time1.m=b;time1.d=c;
if(isYear(time1.y)==0||checkMon(time1.m)==0||checkDay()==0){
printf("日期格式错误:\n");
return 0;
}else{
printf("please input days\n");
int days;
scanf("%d",&days);
EndDate(days);
printf("%4d/%02d/%02d之后%d天的日期是%d/%02d/%02d",a,b,c,
days,time1.y,time1.m,time1.d);
}
return 0;
}
//输入开始的日期和加上的天数返回最后日期
void EndDate(int days){
int Mdays[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int i,j,k;
for(i=1;i<=days;i++){
if(isYear(time1.y)==1)//是闰年
Mdays[2]=29;
else if(isYear(time1.y)==2)//不是闰年
Mdays[2]=28;
time1.d=time1.d%Mdays[time1.m]+1;
if(time1.d==1){
time1.m=time1.m+1;
}
if(time1.m>12){
time1.y=time1.y+1;
time1.m=time1.m%12;
}
}
}
11.递归练习题
#include <stdio.h>
double fun(int n,double x){
if(n==0) return 1;
else if(n==1) return 2*x;
else return 2*x*fun(n-1,x)-2*(n-1)*fun(n-2,x);
}
int main(){
double x;
int n;
scanf("%d%lf",&n,&x);
printf("%lf\n",fun(n,x));
return 0;
}
12.近似值
#include <stdio.h>
#include <math.h>
#define eps 1e-6
int main(){
double x1,x2=2;
int n=1;
do{
n++;
x1=x2;
x2=pow(1+1.0/n,n);
}while(fabs(x1-x2)>eps);
printf("e的值为%lf,n=%d\n",x2,n);
return 0;
}
13.学生结构体排列列
#include <stdio.h>
#include <math.h>
struct student{
int no;//学号
char name[20];//姓名
double score[3];//三科成绩
double sum;//总成绩
int rank;//排名
};
int main(){
int i,j;double sum;
FILE *fp=fopen("student.dat","w+");
printf("请输入需要输入的学生个数:\n");
int n;
scanf("%d",&n);
struct student stu[n];
printf("输入每个学生的信息:\n");
for(i=0;i<n;i++){
printf("输入第%d个学生的信息\n",i+1);
scanf("%d%s",&stu[i].no,stu[i].name);
sum=0.0;
for(j=0;j<3;j++){
scanf("%lf",&stu[i].score[j]);
sum+=stu[i].score[j];
}
stu[i].sum=sum;
}
struct student temp,k;
//进行排名
int index;
for(i=0;i<n;i++){
k=stu[i];index=i;
for(j=i+1;j<n;j++){
if(k.sum<stu[j].sum){
k=stu[j];
index=j;
}
}
temp=stu[i];
stu[i]=k;
stu[index]=temp;
}
//进行名次排序,总分相同的名次相同
int rank=1;
for(i=0;i<n;i++){
if(i==0){
stu[i].rank=rank;rank++;
}else{
if(stu[i].sum==stu[i-1].sum){
stu[i].rank=stu[i-1].rank;
rank++;
}else{
stu[i].rank=rank;
rank++;
}
}
}
//进行输出
printf("全体学生信息输出:(按总分排序)\n");
printf("学号\t姓名\t数学\t语文\t英语\t总分\t名次\n");
for(i=0;i<n;i++){
printf("%d\t%s\t%lf\t%lf\t%lf\t%lf\t%d\n",stu[i].no,stu[i].name,
stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].sum,stu[i].rank);
fprintf(fp,"%d\t%s\t%lf\t%lf\t%lf\t%lf\t%d\n",stu[i].no,stu[i].name,
stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].sum,stu[i].rank);
}
fclose(fp);
return 0;
}
14.蛇形数组
编写程序,实现将自然数1,2,....N*N按照射型方式存入N介矩阵。
#include <stdio.h>
#include <math.h>
int main(){
int x,y,k,i,j,n,start=1,flag=1;
scanf("%d",&n);
int a[n][n]={0};
for(i=0;i<n;i++){
if(flag==0){
for(x=0;x<=i;x++)
a[x+n-i-1][x]=start++;
flag=1;
}else{
for(x=i;x>=0;x--) a[x+n-1-i][x]=start++;
flag=0;
}
}
int ends=n*n;flag=1;
for(i=n-1;i>0;i--){
if(flag==1){
for(x=i;x<=n-1;x++) a[x-i][x]=ends--;
flag=0;
}else{
for(x=n-1;x>=i;x--) a[x-i][x]=ends--;
flag=1;
}
}
for(i=0;i<n;i++){
for(j=0;j<n;j++){
printf("%4d",a[i][j]);
}
printf("\n");
}
return 0;
}
15.完数
编程求1000之内的所有完数。所谓的完数是指一个数恰好等于他的包含1在内的所有不同因子之和。
eg:6=1+2+3
#include <stdio.h>
#include <math.h>
int fun(int num){//判断这个是是不是完数
int sum=0,i;
for(i=1;i<num;i++){
if(num%i==0) sum+=i;
}
if(sum==num) return 1;//是完数
else return 0;//不是完数
}
int main(){
int i;
printf("1000以内的完数如下:\n");
for(i=1;i<=1000;i++){
if(fun(i)) printf("%4d",i);
}
return 0;
}
16.输入一个字符串,内有数字和非数字字符,如
A123x456$1789>3560tab587
将其中连续的数字字符作为一个整数,依次存放在一数组a中。
例如123放在a[0],放在a[1]....统计共有多少个整数,并输出这些整数。
#include <stdio.h>
#include <math.h>
#define N 20
int a[N];
int main(){
char str[100];
scanf("%s",str);
int i,num=0,k=0;
for(i=0;str[i]!='\0';i++){
if(str[i]>='0'&&str[i]<='9')
num=num*10+str[i]-'0';
else{
if(num==0) continue;
else{
a[k++]=num;num=0;
}
}
}
if(num!=0) a[k++]=num;
for(i=0;i<k;i++){
printf("%6d",a[i]);
}
printf("\n共有%d个数值\n",k);
return 0;
}
17.打印图形
编程打印如下图像,中间一行英文字母由输入得到,图形应随输入的英文字母的变化而变化。
列如:
1.输入A
A
2.输入B
A
BBB
A
#include<stdio.h>
#include<math.h>
void print(char ch){
int i,j,k,len=ch-'A';
for(i=0;i<=len;i++){//上三角的输出
for(j=0;j<len-i;j++) printf(" ");
for(k=0;k<=2*i;k++) printf("%c",'A'+i);
printf("\n");
}
//下三角的输出
for(i=0;i<=len-1;i++){
for(j=0;j<=i;j++) printf(" ");
for(k=0;k<2*len-2*i-1;k++) printf("%c",ch-i-1);
printf("\n");
}
}
int main(){
char ch;
printf("请输入一个字符:");
scanf("%c",&ch);
print(ch);
return 0;
}
四、898预测五套卷
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。