吉林大学计算机系高级语言程序设计(C语言)期末题目及解答(下)

内容简介

因为正在准备考研复试,所以计划把吉大期末的C语言题目重新刷一遍(上机),做为笔记放在这里,有需要的朋友请自提~

注:
①持续更新;
②因为文章过大所以分为了上下两篇,上篇也在我的博客列表里;
③本文所有代码均已测试通过,未通过的会在前面标注【未通过】。

正文

2018级A卷

1.上卷中有一模一样的题,在这里就不写了。

2.编写函数,对n个字符串按照字典序排序。
限定函数名:void sort(char st[],[10],int n)

算法思路:
这个题主要考察二维数组,显然,每个字符串的长度为10,一共有n个字符串。在实现本题的过程中,我单独设立了一个sortone函数(冒泡排序),用于将每个字符串进行排序。
代码实现

#include 
#define N 10

void sort(char st[][N],int n);//多行字符串排序函数 
void sortone(char *s);//单行字符串排序函数 

int main()
{
	printf("\n\n\t——本函数用于对多个字符串进行排序——");
	printf("\n\n\t请输入字符串数量:");
		int n;
		scanf("%d",&n);//用户输入字符串数量 
		while(n<0)
		{
			printf("\n\n\tn需为正数,请重新输入:");
			scanf("%d",&n);
		}
	int i;
	char st[n][N];//用户输入数据 
	for(i=0;i<n;i++)
	{
		printf("\n\n\t请输入第%d个字符串:",i+1);
			scanf("%s",st[i]);
	}
	
	sort(st,n);//调用多行排序函数
	
	printf("\n\n\t排序结果为:\n");
	for(i=0;i<n;i++)
	{
		printf("\n\t%s",st[i]);
		}	
	printf("\n\n\t——算法结束——");
	return 0;
 } 

void sort(char st[][N],int n)
{
	for(int i=0;i<n;i++)//逐行排序 
	{
		sortone(st[i]);
	}
 } 

void sortone(char *s)//单行字符串排序函数
{
	//采用冒泡排序
	int i,j;
	int len=0;
	i=0;
	while(s[i]!='\0')  //统计该字符串长度 
	{
		len++;
		i++;
	 } 
	
	for(i=0;i<len;i++)
	{
		bool change=false;
		for(j=0;j<len-i-1;j++)
		{
			if(s[j]>s[j+1])//交换反序对 
			{
				change=true;
				int temp=s[j];
				s[j]=s[j+1];
				s[j+1]=temp;
			}
		}
		if(change==false)//如果没有交换反序对 ,退出循环,排序完成 
		{
			break;
		}
	}
}

3.编写递归函数,实现对有序数组的二分查找。

算法思路:
首先,此题有两个递归出口
①找不到要搜索的关键值。
因为数组已经是有序数组,查无此值的情况只能是数值比最小的小或者比最大的大,所以直接与端进行比较即可。
②找到关键值
找到关键值直接返回关键值的位置。

其次,递归条件
这道题要想完成递归,比较关键的点就在于如何改变“端”的位置,然后不断和中位值做比较。
在程序中,我将函数名设定为 int Search( int s, int e ,int *a ,int x);
其中,s为起始位置(start),e为终止位置(end),a 是数组名,x是要查找的关键值。
①如果当前中位值就是要查找的关键值,判断条件为a[(s+e)/2]=k;
②如果关键值比中位值要小,则改变端的位置为(s,(s+e)/2);
③如果关键值比中位值要大,则改变端的位置为 ((s+e)/2.e)。

代码实现:

#include 
#define N 20

int Search(int s,int e,int *a,int x);//递归实现有序数组的二分查找
void Sort(int *a,int n);

int main()
{
	printf("\n\n\t请输入数组长度(不超过%d ): ",N);//用户输入数组长度 
		int n;
		scanf("%d",&n);
		while((n<0)||(n>N))
		{
			printf("\n\n\t长度区间为0~%d,请重新输入: ",N);
			scanf("%d",&n);
		}
	printf("\n\n\t请输入数组数据: ");//用户输入数组数据 
		int a[N];
		for(int i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
		}
	
	printf("\n\n\t——正在排序——\n\n\t");
		Sort(a,n);
	for(int j=0;j<n;j++)
	{
		printf("%d ",a[j]);
	}
	printf("\n\n\t——排序完成——"); 
	
	printf("\n\n\t请输入要查找的关键值: ");//输入关键值 
		int x;
		scanf("%d",&x);
	
	int res=Search(0,n-1,a,x);//调用二分查找函数
	if(res==-1)
	{
		printf("\n\n\t查无此数。");
	 } 
	else
	{
		printf("\n\n\t%d 的位置为第 %d 个。",x,res+1);
	}
	
	printf("\n\n\t——算法结束——");
	return 0;
 } 

int Search(int s,int e,int *a,int x)
{
	int k=(s+e)/2;
	int i=0,n=0;
	while(a[i]!='\0')
	{
		i++;
		n++;
	}
	if((x<a[0])||(x>a[n-1])) //找不到的情况 
	{
		return -1;//因为有序,直接和端比较就行了 
	}
	if(x==a[k])
	{
		return k;
	}
	else if(x<a[k])//向左查找 
	{
		return Search(s,k,a,x);
	}
	else //向右查找 
	{
		return Search(k,e,a,x);
	}
}

void Sort(int *a,int n)
{
	for(int i=0;i<n;i++)
	{
		bool change=false;
		for(int j=0;j<n-i-1;j++)
		{
			if(a[j]>a[j+1])
			{
				int temp;
				temp=a[j];
				a[j]=a[j+1];
				a[j+1]=temp;
				change=true;
			}
		}
		if(change==false)
		{
			break;
		}
	}
}

4.成绩信息包含:姓名,学号,讨论成绩,报告成绩,测试成绩五项信息,规定:
实验成绩 = 讨论成绩(20%)+报告成绩(20%)+测试成绩 (60%)
1)创建结点类型;
2)假如所有信息都存储在文件2018.txt中,创建链表;
3)【原第五题,我放在一起写了】对题中的里链表按实验成绩,从高到低排序

算法思路:
①本科为了期末题而来的朋友请注意,这种链表题一定一定要写头文件,有两分;
②第二小问考察的知识点为:从文件读,创建链表;
③第三小问考察排序和链表内换位。

注意:
1)期末题对排序算法要求不高,数组排序我一般会用冒泡排序,链表排序用直接插入(没有新建链表,就是在同一个链表中操作);
2)文件存储位置我选在了E盘目录下,大家调试的时候可以自己更改存储路径;
3)为了测试方便我增添了一个向文件写入的函数,第一次输入数据的时候可以先选择从键盘写入文件,这样后面从文件读取的时候也方便;
4)这个程序还可以再改进,就是在用户对链表排序之后,把排序后的链表再次保存进文档中,改进方法为再写一个从链表写入文件的函数,也非常简单,可以参照从键盘写入的write()函数进行编写。

代码实现:

#include 
#include 
#define N 20
              //多么朴实无华的元素名 
struct Node{
	int num;   //学号 
	char name[N];  //姓名 
	int taolun;  //讨论成绩 
	int baogao;  //报告成绩 
	int ceshi;  //测试成绩 
	float shiyan;  //实验成绩 
	struct Node *next;
};

//函数声明
struct Node * Create();//从文件创建链表函数
struct Node * Sort(struct Node * head);//对链表进行排序
void Show(struct Node *head);//显示函数
void Write();//向文件写入的函数 

int main()
{
	printf("\n\n\t——本程序用于处理学生信息——");
	//写入文件 
	printf("\n\n\t请问是否需要写入文件?第一次使用本程序需写入。(是-1,否-0)");
		int x;
		scanf("%d",&x);
		while((x!=1)&&(x!=0))
		{
			printf("\n\n\t只能输入1或0,请重新输入:");
			scanf("%d",&x);
		}
	if(x==1)
	{
		Write();
	}
	
	//建立链表
	printf("\n\n\t——现在开始创建链表——");
	 struct Node * head=Create();
	Show(head); 
	printf("\n\n\t——链表建立完成——");
	
	
	//排序链表
	printf("\n\n\t——对链表进行排序——");
	struct Node *nhead=Sort(head);
	Show(nhead);
	printf("\n\n\t——排序完成——");
	
	printf("\n\n\t——算法结束——");
	return 0;
 } 

void Write()
{
	FILE *fp;
	if((fp=fopen("E://2018.txt","w+"))==NULL)
	{
		printf("\n\n\t文件打开失败。");
		exit(0);
	}
	
	int n,t,b,c;
	float s;
	char na[N];
	
	int i=1,x=1;
	while(x==1)
	{
		printf("\n\n\t请输入第 %d 个学生信息:",i);
		i++;
		printf("\n\t姓    名:");
			scanf("%s",na);
		printf("\n\t学    号:");
			scanf("%d",&n);
		printf("\n\t讨论成绩:");
			scanf("%d",&t);
		printf("\n\t报告成绩:");
			scanf("%d",&b);
		printf("\n\t测试成绩:");
			scanf("%d",&c);
		s=t*0.20+b*0.20+c*0.60;
		//向文件写入 
		fprintf(fp,"%s %d %d %d %d %.2f\n",na,n,t,b,c,s);
		
		printf("\n\n\t继续输入请键入1,否则键入0: ");
			scanf("%d",&x);
			while((x!=1)&&(x!=0))
			{
				printf("\n\n\t只能输入1或0,请重新输入: ");
				scanf("%d",&x);
			}
	}
	fclose(fp);//关闭文件 
}

struct Node * Create()
{
	FILE *fp;
	if((fp=fopen("E://2018.txt","r"))==NULL)
	{
		printf("\n\n\t文件打开失败");
		exit(0);
	}
	
	struct Node *p,*head,*p0;
	p=(struct Node *)malloc(sizeof(struct Node));
	head=p;
	
	fscanf(fp,"%s %d %d %d %d %f",(*p).name,&(*p).num,&(*p).taolun,&(*p).baogao,&(*p).ceshi,&(*p).shiyan);
	(*p).next=NULL;
	p0=p;
	//从文件读入并创建链表 
	while(fgetc(fp)!=EOF)
	{
		p0=p;
		p=(struct Node *)malloc(sizeof(struct Node));
		(*p0).next=p;
		fscanf(fp,"%s %d %d %d %d %f",(*p).name,&(*p).num,&(*p).taolun,&(*p).baogao,&(*p).ceshi,&(*p).shiyan);
		(*p).next=NULL;
	}

	return head;
}

struct Node *Sort(struct Node *head)
{
	struct Node *p,*tail;//tail为尾结点
	p=head;
	while((*p).next!=NULL)
	{
		p=(*p).next;
	 } 
	tail=p;  //找到尾结点的位置
	
	struct Node *q=head; //标记有序结尾 
	struct Node *k;
	struct Node *p0;
	k=(*q).next;//k结点为当前要向前插入的结点	
	
	while(q!=tail)//遍历整个链表 
	{	
		//给k结点找位置
		p=head;
		p0=p;
		while((*p).shiyan<(*k).shiyan)
		{
			p0=p;
			p=(*p).next;
		 }
		//插入k结点
		if(p==head)
		{
			(*q).next=(*k).next;
			(*k).next=p;
			head=k;
			k=(*q).next;
		 } 
		else if(p==k)
		{
			q=(*q).next;
			k=(*q).next;
		}
		else
		{
			(*q).next=(*k).next;
			if((*k).next==NULL)
			{
				tail=q;
			}
			(*p0).next=k;
			(*k).next=p;
			k=(*q).next;
		}
	 } 
	return head;
}

void Show(struct Node *head)
{
	struct Node *p;
	p=head;
	while((*p).next!=NULL)
	{
	printf("\n\n\t姓名:%s  学号:%d  讨论成绩:%d  报告成绩:%d  测试成绩:%d 实验成绩:%.2f",(*p).name,(*p).num,(*p).taolun,(*p).baogao,(*p).ceshi,(*p).shiyan);
	p=(*p).next;
	}
}

附加

1.编写程序实现:用户从键盘输入N值,实现下面的函数:要求:不可使用递归;只能使用一个数组且数组的大小最大不超过4。
F(n)= 1 (n=1)
2 (n=2)
3 (n=3)
4 (n=4)
F(n-1)+f(n-4) (n>=5)

算法思想:
这道题本身很简单,但需注意题设要求:
①虽然是典型的递归式,但不允许使用递归的算法;
②使用的数组容量很小,而且只能使用一个数组。

算法设计:
虽然存储空间只有4,但实际上每次运算需要用到的也只有四个数据,每次计算之后对数组进行一次“集体向左覆盖”,然后把算出的结果存入第一个数据的位置;
比如,算出F(5)以后,把F(5)存进以前F(1)的位置;

代码实现:

#include 

int CalF(int n);//迭代计算函数 

int main()
{
	printf("\n\n\t请输入n值:");//用户输入n值 
		int n;
		scanf("%d",&n);
		while((n<1)||(n>100))
		{
			printf("\n\n\tn值的取值为1-100的整数,请重新输入:");
			scanf("%d",&n);
		}
	printf("\n\n\t计算结果为: %d",CalF(n));//调用计算函数并输出结果 
	printf("\n\n\t——算法结束——");
	return 0;
}

int CalF(int n)
{
	int a[4];
	for(int i=1;i<5;i++)//初始化数值 
	{
		a[i-1]=i;
	}
	
	if(n==1)
		return a[0];
	else if(n==2)
		return a[1];
	else if(n==3)
		return a[2];
	else if(n==4)
		return a[3];
	else
	{
		int i;
		for(i=0;i<n-4;i++)
		{
			int temp=a[0]+a[3];   //计算F(n) 
			for(int j=0;j<3;j++)  //逐个向左覆盖 
			{
				a[j]=a[j+1];
			}
			a[3]=temp;
		}
		return a[3];  //返回F[n] 
	}
}

2.编写程序实现:若一个数字的各个数位阶乘之和等于它本身,则称该数字为一个阶乘数,如(145=1!+4!+5!),输出除1,2之外,小于2000000的所有阶乘数。

算法思想:
①设立一个单独的阶乘计算函数;
②分离数位;

代码实现:

#include 

int fac(int n);//计算n的阶乘
bool ifac(int x);//判断x是不是一个阶乘数

int main()
{
	printf("\n\n\t——请输入x值——");
		int x;
		scanf("%d",&x);
	bool res=ifac(x);
	if(res==true)
	{
		printf("\n\n\t是。");
	}
	else{
		printf("\n\n\t否。");
	}
	printf("\n\n\t——算法结束——");
	return 0;
 } 

bool ifac(int x)//判断是否是阶乘数 
{
	int sum=0;
	int temp;
	int savex=x;
	while(x!=0)   //直接加就行了,不用存
	{
		temp=x%10;
		sum=sum+fac(temp);
		x=x/10;
	}
	if(savex==sum)
		return true;
	else
		return false;
}

int fac(int n)
{
	if(n==1)//递归出口 
		return 1;
	else
		return n*fac(n-1);
 } 

2010级A卷

1.编一函数,求一个NXM的二维整形数组中各元素的平均值和最大值。
算法思想:
1)本题主要考察对二维数组的操作;
2)此外需注意计算平均值的时候不要让整数除法影响最后的结果,应该注意浮点型转换问题。

代码实现:

#include 
#define N 3//规定行数 
#define M 2//规定列数

void AverMax(int a[][M],int n);//目标函数

int main()
{
	printf("\n\n\t请输入一个%dX%d的数组:",N,M);
	int a[N][M];
	//用户输入数据 
	for(int i=0;i<N;i++)
	{
		printf("\n\t");		
		for(int j=0;j<M;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	//调用函数
	AverMax(a,N);
	printf("\n\n\t——算法结束——");
	return 0; 	
 } 
 
void AverMax(int a[][M],int n)
{
	int i,j;
	int sum=0;
	int max=a[0][0];
	 
	for(i=0;i<n;i++)
	{
		for(j=0;j<M;j++)
		{
			sum=sum+a[i][j];
			if(a[i][j]>max)
			{
				max=a[i][j];
			}
		}
	}
	
	int k=M*n;
	float aver=float(sum)/k;//计算平均值,注意浮点数转换
	
	printf("\n\n\t平均值为: %.2f",aver);
	printf("\n\n\t最大值为: %d",max); 
}

2.编一函数,完成NXN的整形数组 a的赋值,其中,a的各元素值如下图所示,未显示的其他元素值均为0.
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
6 12 18 24 30 36
……
9 18 27 36 45 54 63 72 81

算法思路:
①这是一个下三角形矩阵,如果追求格式一等一整齐,则个位数之间打两个空格,两位数不打空格;
②打印矩阵类题目需要着重注意两个问题:第一,如何换行;第二,数据之间的规律。

代码实现:

#include 
#define N 9

int main()
{
	int a[N][N];//定义一个NXN的二维数组

	int i,j;
	for(i=0;i<N;i++)
	{
		for(j=0;j<i+1;j++)//为下三角赋值 
		{
			a[i][j]=(i+1)*(j+1);
		}
		for(j=i+1;j<N;j++)//将上三角置零 
		{
			a[i][j]=0;
		}
	}
	
	printf("\n\n\t——矩阵显示为——\n");
	for(i=0;i<N;i++)
	{
		printf("\n\t");//每行换行 
		for(j=0;j<N;j++)
		{
			if(a[i][j]==0)
			{
				printf("  ");
			}
			else if(a[i][j]<10)
			{
				printf("%d  ",a[i][j]);
			}
			else{
				printf("%d ",a[i][j]);
			}
		}
	}
	printf("\n\n\t——矩阵显示完毕——");
	return 0;
}

3.编写一个递归函数,计算f(n)=a!+b!+c!+d!,其中a,b,c,d都是n的各个数位。
(此题考查递归函数与分离数位,已经在上文的“附加”部分做过,请自行查询。)

4.编一函数,完成对字符串参数的判断,如果该字符是对称字符串,函数值返回1,如果不是则返回零。

#include 
#define N 20
int IsSymm(char *s);//判断字符串是否对称

int main()
{
	printf("\n\n\t请输入字符串: ");
		char s[N];
		scanf("%s",s);
		
	int res=IsSymm(s);//调用判断函数 
	if(res==1)
	{
		printf("\n\n\t对称。");	
	}
	else 
	{
		printf("\n\n\t不对称。");
	}
	
	printf("\n\n\t——算法结束——");
	return 0;
 } 
 
int IsSymm(char *s)
{
	int len=0,i=0;
	while(s[i]!='\0')//统计字符串长度 
	{
		len++;
		i++;
	}

	for(i=0;i<len/2;i++)
	{
		if(s[i]!=s[len-i-1])//出现了不对称的字符 
		{
			return 0;
		}
	}
	return 1;	//只有全都对称才能执行到这一步 
}

5.某班学生的信息包括学号、姓名、性别、成绩等信息。
1)完成学生信息的结构定义;
2)编写一个名为CreatList的函数实现建立具有n个节点的链表来存储这个班的学生信息;
3)编一函数WriteFile,将该班的信息存入文件。

#include 
#include 

struct Node{
	int num;  //学号
	char name[20];  //姓名
	int sex;   //性别,男-1 ,女-0
	int grade;  //成绩
	struct Node *next;  //后继指针 
};

struct Node * CreatList();//建立链表函数
void WriteFile(struct Node *head);  //存入文件
void Show(struct Node *head);//显示函数 

int main()
{
	printf("\n\n\t——建立链表——");
	struct Node *head =CreatList();
	Show(head);
	printf("\n\n\t请问是否存入文件,存入请输入1,否则输入0: ");
		int x;
		scanf("%d",&x);
		while((x!=1)&&(x!=0))
		{
			printf("\n\n\t只能输入0或1,请重新输入: ");
			scanf("%d",&x);
		 } 
	if(x==1)
	{
		WriteFile(head);
	}
	printf("\n\n\t——算法结束——");
	return 0;
 } 

struct Node* CreatList()
{
	struct Node *p,*head,*p0;
	p=(struct Node*)malloc(sizeof(struct Node));
	head=p;

	printf("\n\n\t姓名: ");
		scanf("%s",(*p).name);
	printf("\n\n\t学号: ");
		scanf("%d",&(*p).num);
	printf("\n\n\t性别(男-1,女-0): ");
		scanf("%d",&(*p).sex);
		while(((*p).sex!=1)&&((*p).sex!=0))
		{
			printf("\n\n\t只能输入1或0,请重新输入: ");
			scanf("%d",&(*p).sex);
		}
	printf("\n\n\t成绩: ");
		scanf("%d",&(*p).grade);
	(*p).next=NULL;
	printf("\n\n\t请问是否要继续输入?是-1;否-0: ");
	int x;
		scanf("%d",&x);
		while((x!=1)&&(x!=0))
		{
			printf("\n\n\t只能输入0或1,请重新输入: ");
			scanf("%d",&x);
		 } 
	
	while(x==1)
	{
		p0=p;		
		p=(struct Node*)malloc(sizeof(struct Node));
		printf("\n\n\t姓名: ");
			scanf("%s",(*p).name);
		printf("\n\n\t学号: ");
			scanf("%d",&(*p).num);
		printf("\n\n\t性别(男-1,女-0): ");
			scanf("%d",&(*p).sex);
			while(((*p).sex!=1)&&((*p).sex!=0))
			{
				printf("\n\n\t只能输入1或0,请重新输入: ");
				scanf("%d",&(*p).sex);
			}
		printf("\n\n\t成绩: ");
			scanf("%d",&(*p).grade);
		(*p).next=NULL;
		(*p0).next=p;
		
		printf("\n\n\t请问是否要继续输入?是-1;否-0: ");

			scanf("%d",&x);
			while((x!=1)&&(x!=0))
			{
				printf("\n\n\t只能输入0或1,请重新输入: ");
				scanf("%d",&x);
		 	} 
		}
	return head;	
}

void WriteFile(struct Node* head)
{
	FILE *fp;
	if((fp=fopen("E://write.txt","w"))==NULL)
	{
		printf("\n\n\t文件打开错误。");
		exit(0);
	}
	
	struct Node *p=head;
	while(p!=NULL)
	{
		fprintf(fp,"\n\n");
		fprintf(fp," 姓名:%s",(*p).name);
		fprintf(fp," 学号:%d",(*p).num);
		fprintf(fp," 性别:");
		if((*p).sex==0)
		{
			fprintf(fp,"女");
		}
		else
		{
			fprintf(fp,"男"); 
		}
		fprintf(fp,"成绩: %d",(*p).grade);
		p=(*p).next;
	}
	printf("\n\n\t——写入文件完毕——");
}

void Show(struct Node *head)
{
	struct Node *p=head;
	while(p!=NULL)
	{
		printf("\n\n\t");
		printf(" 姓名:%s",(*p).name);
		printf(" 学号:%d",(*p).num);
		printf(" 性别:");
		if((*p).sex==0)
		{
			printf("女");
		}
		else
		{
			printf("男"); 
		}
		printf("成绩: %d",(*p).grade);
		p=(*p).next;
	}
}

2004级A卷

1.编程序,打印前十对孪生素数。若两个素数之差为2,则称为孪生素数,例如(3,5)(5,7)(11,13)

设计思路:
①单独设置一个判断素数的函数,返回值为布尔变量,是素数则返回true,不是则返回false;
②从2开始向正方向遍历正整数,设置计数器,每输出一对计数器就加一,直到计数器累积为10为止。

代码实现:

#include 

bool IsPrime(int x);//判断参数x是不是素数的函数
void TenPrime(int n);//输出前十对孪生素数的函数

int main()
{
	printf("\n\n\t——本程序用于输出前N对孪生素数——");
	printf("\n\n\t请输入n值:");
		int n;
		scanf("%d",&n);
		while(n<0)
		{
			printf("\n\n\t输入值需大于零,请重新输入:");
			scanf("%d",&n);
		}
	TenPrime(n);
	printf("\n\n\t——算法结束——");
	return 0;
 } 
 
bool IsPrime(int x)//素数判断函数 
{
	if(x==1)//1的特殊处理 
		return false;
	for(int i=2;i<x/2;i++)
	{
		if(x%i==0)
			return false;  //非素数返回false 
	}
	return true;//能运行到这里就是素数,返回true 
}

void TenPrime(int n)
{
	int i=0;
	int k=2;
	while(i<n)
	{
		if((IsPrime(k)==true)&&(IsPrime(k+2)==true))
		{
			printf("\n\n\t第%d对: (%d ,%d)",i+1,k,k+2);
			i++;//计数已经输出了多少对 
		}
		k++;
	}
}

2.设幂数为非负整数的多项式。将每一项的系数和幂次存于下表:

幂次 幂次
系数 系数

设计保存多项式的数据结构并编写一个函数计算多项式的值。
设计思路:

  1. 设计一个结构体,里面包含两项:幂次和系数;
  2. 使用链表解决该问题,这样用户就不必提前输入多项式一共有多少项。

代码实现:

#include 
#include 

struct Node{
	int mi;//幂次 
	float xi;//系数 
	struct Node *next;//后继指针 
};

struct Node * Create();//建立链表——用户输入多项式
void Show(struct Node *head);//展示链表
float Cal(struct Node* head ,int x);//计算多项式的值

int main()
{
	printf("\n\n\t——本程序用于计算多项式的值——");

	printf("\n\n\t请建立多项式:");  //用户建立多项式 
	struct Node *head=Create();
	printf("\n\n\t您建立的多项式为: ");//展示多项式 
	Show(head);
	
	int x1=1;	
	while(x1==1)
	{
	printf("\n\n\t请输入x的值: ");   //用户输入x值 
		int x;
		scanf("%d",&x);
	printf("\n\n\t当x 的值为 %d时,计算结果为 %.2f.",x,Cal(head,x));//调用计算函数并输出结果
	
	printf("\n\n\t请问是否要继续输入X值?是——1,否——0:  ");
		scanf("%d",&x1);
		while((x1!=1)&&(x1!=0))
		{
			printf("\n\n\t只能输入1或0,请重新输入: ");
			scanf("%d",&x1);
		}			
	}

	
	 
	printf("\n\n\t——算法结束——");
	return 0;
	
 } 

struct Node* Create()//建立链表——用户输入多项式
{
	struct Node *head,*p,*p0;
	p=(struct Node*)malloc(sizeof(struct Node));
	head=p;
	
	int i=1;
	printf("\n\n\t请输入第%d项的系数: ",i);
		scanf("%f",&(*p).xi);
	printf("\t请输入第%d项的幂次: ",i);
		scanf("%d",&(*p).mi);
		i++;
	(*p).next=NULL;
	
	printf("\n\n\t请问多项式结束了吗?结束——0;未结束——1:  ");
		int x;
		scanf("%d",&x);
		while((x!=0)&&(x!=1))
		{
			printf("\n\n\t只能输入0或1,请重新输入: ");
			scanf("%d",&x);
		}
	
	while(x==1)
	{
		p0=p;
		p=(struct Node*)malloc(sizeof(struct Node));
		
		printf("\n\n\t请输入第%d项的系数: ",i);
			scanf("%f",&(*p).xi);
		printf("\t请输入第%d项的幂次: ",i);
			scanf("%d",&(*p).mi);
			i++;
		(*p).next=NULL;
		(*p0).next=p;
	
		printf("\n\n\t请问多项式结束了吗?结束——0;未结束——1:  ");
			scanf("%d",&x);
			while((x!=0)&&(x!=1))
			{
				printf("\n\n\t只能输入0或1,请重新输入: ");
				scanf("%d",&x);
				}
	}

	return head;	
}

void Show(struct Node *head)
{
	struct Node *p=head;
	while(p!=NULL)
	{
		printf(" %.1fX(%d)  ",(*p).xi,(*p).mi);
		if((*p).next!=NULL)  //最后一项前面不加+号 
		{
			printf("+");
		}
		p=(*p).next;
	}
}

float Cal(struct Node *head,int x)
{
	struct Node*p=head;
	float sum=0;
	while(p!=NULL)
	{
		int temp=1;
		for(int i=0;i<(*p).mi;i++)
		{
			temp=temp*x;
		}
		sum=sum+(((*p).xi)*temp);
		p=(*p).next;
	}
	return sum;
}

3.编程序判断10阶整数方阵是否关于主对角线对称。
算法思路:

假设用i计数器来计数行,用j计数器来计数列,那么关于主对角线对称的两个元素的下标应该为:a[i][j] 和 a[j][i]
在遍历判断的时候,只需要遍历上三角矩阵或者下三角矩阵,如果遍历下三角矩阵,则使用二重循环,第二层的控制条件是j

代码实现:

#include 
#define N 3

bool IsSymm(int a[][N],int n);//判断二维数组是不是沿主对角线对称 

int main() 
{
	printf("\n\n\t请输入矩阵(%d X %d): \n",N,N);
		int a[N][N];
		int i,j;
		for(i=0;i<N;i++)
		{
			printf("\t");
			for(j=0;j<N;j++)
			{
				scanf("%d",&a[i][j]);
			}
		}
	if(IsSymm(a,N)==true)
	{
		printf("\n\n\t对称");
	}
	else
	{
		printf("\n\n\t不对称");
	}
	return 0;
 } 
 
bool IsSymm(int a[][N],int n)
{
	int i,j;
	for(i=0;i<n;i++)
	{
		for(j=0;j<N/2;j++)
		{
			if(a[i][j]!=a[j][i])
				return false;
		}
	}
	return true;
}

4.编一个函数,用冒泡法实现由整数组成的单向链表的排序。

算法思想:
和数组的冒泡排序其实没有区别,冒泡排序是交换排序的一种,关键点在于交换反序对。

代码实现:

#include 
#include 
struct Node{
	int data;  //数据域 
	struct Node *next;  //后继指针 
};

struct Node * Create(int n);//创建链表函数
struct Node * BSort(struct Node *head,int n);//链表版冒泡排序 
void Show(struct Node *head);//显示函数 
 

int main()
{
	printf("\n\n\t请输入链表长度: ");
		int n;
		scanf("%d",&n);
	printf("\n\n\t请输入链表数据: ");
	struct Node *head=Create(n);
	
	Show(head);
	printf("\n\n\t——正在对链表进行排序——");
	struct Node *newhead;
	newhead=BSort(head,n);
	
	printf("\n\n\t排序后的链表为: ");
	Show(newhead);
	
	return 0;
 } 
 
struct Node *Create(int n)
{
	struct Node *head,*p,*p0;
	p=(struct Node *)malloc (sizeof(struct Node));
	
	scanf("%d",&(*p).data);
	(*p).next=NULL;
	head=p;
	
	for(int i=1;i<n;i++)
	{
		p0=p;
		p=(struct Node *)malloc(sizeof(struct Node));
		scanf("%d",&(*p).data);
		(*p).next=NULL;
		(*p0).next=p;
	}
	
	return head;	
}

struct Node * BSort(struct Node* head,int n)
{
	struct Node *p=head;
	struct Node *q=(*p).next;//q是p的后继结点 
	struct Node *p0=p;//p0是p的前驱结点 
	int i,j;
	for(i=0;i<n;i++)
	{
		bool swap=false;
		p=head;
		q=(*p).next;
		p0=p;
		for(j=0;j<n-i-1;j++)
		{
			if((*p).data>(*q).data)
			{
				swap=true;
				if(p==head)//头结点特殊处理 
				{
					(*p).next=(*q).next;
					(*q).next=p;
					head=q;
					p0=q; 
					q=(*p).next;
				 } 
				else
				{
					(*p).next=(*q).next;
					(*q).next=p;
					(*p0).next=q;
					p0=q;
					q=(*p).next;
				}
			}
			else
			{
				p0=p;
				p=q;
				q=(*q).next;
			}
		}
		if(swap==false)//不交换反序对了就退出循环 
		{
			break;
		}
	}
	return head;
}

void Show(struct Node *head)
{
	printf("\n\n\t");
	struct Node* p;
	p=head;
	while(p!=NULL)
	{
		printf("%d ",(*p).data);
		p=(*p).next;
	}
}

2007级

一、验证角谷猜想:任意给定一个整数,若为偶数则除以2;若为奇数则乘三再加一,得到一个新的自然数之后按照上面的法则继续演算,若干次后得到的结果必为1。

 #include 

void JiaoGu(int x);

int main()
{
	int k=1;
	while(k==1)
	{
		printf("\n\n\t请输入一个整数: ");
			int x;
			scanf("%d",&x);
			JiaoGu(x);
		printf("\n\n\t请问是否要进行角谷验证?是——1;否——0:  ");
			scanf("%d",&k);
			while((k!=1)&&(k!=0))
			{
				printf("\n\n\t只能输入1或0,请重新输入: ");
				scanf("%d",&k);
			 } 
	}
	printf("\n\n\t——算法结束——");
	return 0;
}

void JiaoGu(int x)
{
	int i=0;
	int temp=x;
	while(x!=1)
	{
		i++;
		if(x%2==0)
		{
			x=x/2;
		}
		else
		{     
			x=x*3+1;
		}
	}
	printf("\n\n\t%d 经过 %d 次角谷验证,结果为1.",temp,i);
}

你可能感兴趣的:(吉大期末题)