编程题:
7.1:
求解一般集合的并集问题。
已知两个集合A和B,现要求一个新的集合A=AUB。例如,设
A=(7,5,3,11)
B=(2,6,3)
合并后 A=(7,5,3,11,2,6)
输入格式:
第一行输入集合A的元素个数,第二行输入集合A的各元素值。
第三行输入集合B的元素个数,第四行输入集合B的各元素值。
输出格式:
输出完成合并后的集合A。
//这个题目就可以用到我在实验一中提到的方法,通过一个顺序表就能够实现
具体代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MAXSIZE 10000
typedef int ElemenType;
typedef int Position;
typedef struct LNode*List;
struct LNode{
ElemenType data[MAXSIZE];
Position last;
};
List MakeEmpty(){
List L = (List)malloc(sizeof(struct LNode));
if(L == NULL){
printf("内存分配失败!\n");
exit(1);
}
L->last = -1;
return L;
}
bool search(List L,int temp){
for(int i = 0;i <= L->last;i++){
if(temp == L->data[i]){
return false;
}
}
return true;
}
int main(){
List L;
L = MakeEmpty();
int temp;
int n,m;
int cnt = 0;
scanf("%d",&n);
for(int i = 0;i < n;i++){
scanf("%d",&L->data[i]);
L->last = i;
}
scanf("%d",&m);
for(int i = 0;i < m;i++){
scanf("%d",&temp);
if(search(L,temp) && L->last + 1 < MAXSIZE){
//输出即比较,不用再使用新的顺序表来对比
L->last++;
L->data[L->last] = temp;
cnt++;
}
}
//符合条件则加到原来的顺序表里,不符合条件则进行下一轮的循环
for(int i = 0;i < n+cnt;i++){
printf("%d ",L->data[i]);
}
free(L);
return 0;
}
//对比这道题和实验一中的题目我们可以发现,两道题的要求有根本的区别,这道题要求数值不能重复,所以我们加上了条件的判断,总的来说,这种方法是优于实验一的方法的,建议大家使用这种方法,实验一的答案我就不再修改,供大家对比和借鉴。
7.2:
一元多项式的加法(顺序数组版)
输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数。数字间以空格分隔。
输出格式:
输出1行,以指数递降方式输出和多项式非零项的系数和指数(保证不超过整数的表示范围)。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。
代码答案:
#include<stdio.h>
#include<stdlib.h>
struct monomial{
int coefficient;
int index;
};//定义结构体 monomial 为一元多项式的英文
//coefficient 为系数的英文
//index为指数的英文
void if_first_print(int ft){
if(ft == 0){
printf(" ");
}
}//构建一个void型的函数,方便于后续空格条件判断
int main(){
int n,m;
scanf("%d",&n);
struct monomial mon_one[n];//定义一个一元多项式的结构数组
for(int i = 0;i < n;i++){
scanf("%d %d",&mon_one[i].coefficient,&mon_one[i].index);
}
getchar(); //清除缓冲区
scanf("%d",&m);
struct monomial mon_two[m];
for(int i = 0;i < m;i++){
scanf("%d %d",&mon_two[i].coefficient,&mon_two[i].index);
}
int i = 0, j = 0;//定义两个指针,分别指向两个结构数组
int ft = 1;//定义一个参数,判断是否是首位输出
int zero = 1;//判断是否存在系数指数为0的情况
while(i < n && j < m){
//循环条件为i,j是否超出数组范围
if(mon_one[i].index > mon_two[j].index){
if_first_print(ft);//调用并执行刚刚的函数程序
printf("%d %d", mon_one[i].coefficient, mon_one[i].index);
ft = 0;
zero = 0;
i++;
}
else if(mon_one[i].index == mon_two[j].index){
int sum_coeff = mon_one[i].coefficient + mon_two[j].coefficient;
if(sum_coeff != 0){
if_first_print(ft);
printf("%d %d", sum_coeff, mon_one[i].index);
ft = 0;
zero = 0;
}
i++;
j++;
}
else{
if_first_print(ft);
printf("%d %d", mon_two[j].coefficient, mon_two[j].index);
ft = 0;
zero = 0;
j++;
}
}
while(i < n){
//处理第一个多项式有剩余的情况
if_first_print(ft);
printf("%d %d", mon_one[i].coefficient, mon_one[i].index);
ft = 0;
zero = 0;
i++;
}
while(j < m){
//处理第二个多项式有剩余的情况
if_first_print(ft);
printf("%d %d", mon_two[j].coefficient, mon_two[j].index);
ft = 0;
zero = 0;
j++;
}
if(zero){
//处理零项式的情况
printf("0 0");
}
return 0;
}
//本题解主要是运用了结构数组的方式来解决一元多项式的加法问题,主要思路是运用双指针,依次遍历数组,找到指数大的输出,如果指数相同则相加,最后再处理剩余的数组,后续也会更新使用链表方法解决此类问题的题解。
函数题
6.1:
目的:
本题要求实现一个函数,判断字符串是否是回文。如果是则返回1,否则返回0。
裁判测试程序样例:
#include <stdio.h>
#define N 100
int isecho(char a[]);
int main()
{
char a[N];
int k;
scanf("%s",a);
k=isecho(a);
if(k)
printf("%s yes",a);
else
printf("%s no",a);
return 0;
}
/* 请在这里填写答案 */
代码答案:
int isecho(char a[]){
if (a[0] == '\0'){
return 1;
}//引入对空字符的处理,如果字符为‘0’,也为回文字符
char *p = a;//引入指针P
while(*p != '\0'){
p++;
}
p--;使指针p指向字符串的末尾
char *k = a;引入指针k,使k指向字符串的开头
while(p > k){
if(*p != *k){
return 0;
}
//功能代码,在while(p>k),即p指针在k指针右侧时,执行循环,如果不满足条件则不为回文数,返回0
p--;
k++;
//指针继续移动位置,k指针指向它的后一个位置,p指针指向它的前一个位置
}
return 1;
//最后循环结束,因为没有不满足条件的位数,所以该字符串是回文字符
}
//本题目的题解巧妙的使用了指针的构思,通过首位夹击的方式,按顺序对比每一位的值,这样的思想同样可以用在处理数字类型数据上。本题解还引入了对‘0’字符的考量,建议读者们在编写程序时多考虑一下如何优化程序的健壮性,这样能够保证自己的程序出更少的bug。
//在此再提出一种构造字符串末尾指针的方法:
1.求出字符串长度
2.最后一位的地址=首地址+字符串长度-1
这种方法避免了使用while循环,更简便更快捷,与上文中的答案可以进行替换
6.2:
目的:统计每列最小元素
找出二维数组每列中最小元素,并依次放入b所指一维数组中
裁判测试程序样例:
#include <stdio.h>
#define M 3
#define N 4
void small(int a[][N],int b[]);
int main()
{
int i,j,x[M][N],y[N];
for(i=0;i<M;i++)
for(j=0;j<N;j++)
scanf("%d",&x[i][j]);
small(x,y);
for(i=0;i<N;i++)
printf("%d ",y[i]);
return 0;
}
/* 请在这里填写答案 */
代码答案:
void small(int a[][N], int b[]) {
for (int i = 0; i < N; i++){
int min = a[0][i];
for (int j = 1; j < M; j++) {
if (a[j][i] < min) {
min = a[j][i];
}
}
b[i] = min;
}
}
//本题解使用了较为简单的双重for循环比较和元素放置的方法。需要注意的是,不要把行和列搞混了,我第一次就是因为把这俩东西搞混了,所以题目报错