计算机考研自命题(6)

1、C语言–奇数求和

1、使用函数求奇数和:输入一批正整数(以零或负数为结束标志),求其中的奇数和。要求定义和调用函数 odd(n) 判断数的奇偶

性,当 n 为偶数时返回 0 ,否则返回 1 。试编写相应程序。

/*
解题思路:传入一个数字odd(n)判断 n 是奇数还是偶数,如果是奇数则进行求和
判断奇数是不是奇数 n%2 != 0 就是奇数
*/
# include <stdio.h>

// 判断元素奇偶性
int odd(int n){
	if(n%2==0){  // n是偶数 
		return 0;
	}else{
		return 1;  // n 是奇数 
	} 
} 

int main(){
	int i = 0,len = 0,num,sum = 0;
	int arr[999]; 
	printf("请输入数字:\n");
	scanf("%d",&num);
	while(num!=-1){
		arr[i] = num;
		len++;
		scanf("%d",&num);
		i++;
	}
	// 计算奇数和 
	for(i = 0;i<len;i++){
		if(odd(arr[i]) == 1){
			sum = sum+arr[i];
		}
	}
	
	printf("sum = %d\n",sum);
	return 0;
}

2、C语言–矩阵求和

2、矩阵运算:读入1 个正整数 n(1 ≤n≤6), 再读入n 阶方阵 a,计算该矩阵除副对角线、最后一列和最后一行以外的所有元素之和。

副对角线为从矩阵的右上角至左下角的连线。试编写相应程序。

/*
解题思路:用二维数组构建一个方阵,然后去除副对角线、最后一行最后一列,求和 
i,j为数组下标
副对角线: i+j = n-1
最后一行: i = n-1
最后一列: j = n-1
*/

# include<stdio.h>
int main(){
	int arr[6][6];
	int n,i,j,sum = 0;
	scanf("%d",&n);
	printf("需要构成%d阶方阵\n",n); 
	printf("请输入元素值\n");
	// 数入方阵
	for(i = 0;i<n;i++){
		for(j = 0;j<n;j++){
			scanf("%d ",arr[i][j]);
		}
	} 
	
	// 去除副对角线、最后一行最后一列,求和 
	for(i = 0;i<n;i++){
		for(j = 0;j<n;j++){
			if(i!=n-1&&j!=n-1&&i+j!=n-1){
				sum = sum+arr[i][j];
			} 
		}
	} 
	printf("sum = %d\n",sum); 
	return 0;
} 

3、C语言-文件操作

3、将文件中的数据求和并写入文本文件尾: 文件Int_Data.dat 中存放了若干整数,将文件中所有数据相加, 并把累加和写入该文件

的最后。 试编写相应程序。

/*
解题思路:首先打开文件,利用fscanf()函数从文件中读入一个元素进行求和,feof()函数判断是否到达文件尾,然后将所有元素的和
用fprintf()函数从新写回文件中
*/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main(void){
	
    int number, sum;
    sum = 0;
    FILE *fp1;
    fp1 = fopen("Int_Data.dat", "r+");
    if (fp1 == NULL) {
        printf("Open file error.\n");
        exit(0);
    }

    fscanf(fp1, "%d", &number);       // 从文件中读取一个数字 
    while (!feof(fp1)) {             // 是否读取到文件尾 
        sum += number;
        fscanf(fp1, "%d", &number);
    }
    
    fprintf(fp1, "%d\n", sum);		// 将文件中读取出来的数据和从新写入文件尾 
    fclose(fp1); 
    return 0;
    
}

4、C语言–寻找字符串

4、查找子串 : 输入两个字符串 s 和 t ,在字符串 s 中查找子串 t ,输出起始位置,若不存在,则输出 -1。要求自定义函

char*search(char *s,char *t)返回子串 t 的首地址,若未找到,则迟回NULL。试编写相应程序。

/*
解题思路:输入两个字符串,计算字符串的长度,如果子串 > 主串,那么毕竟失败,
如果子串 < 主串,则开始进行比较,将p指向主串s的首地址,将字串t中的每个字符串和p对比,如果找到一个相同字符则p和t同时向后移动,比较剩下的字符,如果相同的序列返回第一个地址
如果没有找到相同字符则将p向后移动一个,t从头开始,直到将整个s都查找完
*/

# include<stdio.h>
# include<string.h>

char* search(char*s,char*t)
{	
	int size_t=strlen(t),size_s=strlen(s),T,i,j;
	char *p=NULL;
	for(i=0;i<=(size_s-size_t);i++){
		p=s+i;
		T=1;
		for(j=0;j<size_t;j++){
			if(*p!=*(t+j)){
				T=0;
				break;
			}
			p++;
		}
		if(T==1)
			break;
	}
	if(T==0)
		return NULL;
	else
		return s+i;
}


int main(){
	char s[100];
	char t[100];
	char *p;
	printf("请输入主串:");
	scanf("%s", s);
	printf("请输入字串:");
	scanf("%s", t);
	p = search(s, t);
	if(p!=NULL){
		printf("匹配成功,起始位置为:%ld\n", p - s);	
	} else{
		printf("匹配失败!");
	}
	return  0;
}

5、程序填空

5、程序填空(注:<—>代表两个变量的数据交换)。

/*
第一趟将最小的元素放在r[1]中,最大的元素放在r[n]中,
第二趟将第二小的元素放在r[2]中,第二大的元素放在r[n-1]中
以此类推,直到所有序列递增有序
*/


void sort(SqList &r,int n) {
	i=1;
	while((1)______i<n-i-1______________) {
		min=max=1;
		for (j=i+1;(2)__j<n-i-1___ ;++j){
			if((3)__r[j].key<r[min].key___) min=j; 
			else if(r[j].key>r[max].key) 
				max=j;
		}
		if((4)____min != i___) 
			r[min] < ---- >r[j];
		if(max!=n-i+1){
			if ((5)___max == i___) 
				r[min] < ---- > r[n-i+1]; 
			else ((6)___r[max] < ---- > r[n-i+1]; ___);
		}
		i++;
	}
}

6、数据结构–共享栈

6、设有两个栈 s1、s2 都采用顺序栈方式,并共享一个存储区[0,……,maxsize-1],为了尽量利用空间,减少溢出的可能,可采

用栈顶相向、迎面增长的存储方式,试设计s1、s2有关入栈和出栈的操作算法。

/*
解题思路:
共享栈的性质是让两个顺序栈共享一个数组空间,
top[0] 表示 S1 ,top[1] 表示 S2

入栈操作:
当 S.top[1] - S.top[0] == 1时表示栈满
如果栈不满,则判断是在S1还是S2中插入元素,
如果是S1 则s.data[++s.top[0]] = x
如果是S2 则s.data[--s.top[1]] = x

出栈操作:
先判断是S1元素出栈还是S2元素出栈
如果是S1,判断栈是不是为空s.top[0] == -1,不为空进行元素出栈操作s.data[s.top[0]--]
如果是S2,判断栈是不是为空s.top[1] == maxsize,不为空进行出栈操作s.data[s.top[1]++]
*/

# include <stdio.h>
#define maxsize 100   //两个栈共享顺序存储空间所能达到的最多元素数,初识化为100
#define ElemType int       //假设元素类型为整型

typedef struct Stack{
    ElemType data[maxsize];    //栈空间
    int top[2];     //top为两个栈顶指针
}Stack;
Stack s;
//入栈操作
int push(int i,ElemType x){
    //入栈操作,i为栈号,i=0表示左边的s1栈,i=1表示右边的s2栈,x是入栈元素
    //入栈成功返回1,否则返回0
    if(i<0||i>1){
        printf("栈号输入不对");
        exit(0);
    }
    if(s.top[1]-s.top[0]==1){
        printf("栈已满\n");
        return 0;
    }
    switch(i){
        case 0 : s.data[++s.top[0]] = x;
            return 1; 
            break;
        case 1 : s.data[--s.top[1]] = x;
            return 1;
    }
}
//退栈操作
ElemType pop(int i){
    //退栈。i代表栈号,i=0时为s1栈,i=1时为s2栈
    //退栈成功返回退栈元素,否则返回-1
    if(i<0||i>1){
        printf("栈号输入错误\n");
        exit(0);
    }
    switch(i){
    case 0:
        if(s.top[0] == -1){
            printf("栈空\n");
            return -1;
        }
        else{
            return s.data[s.top[0]--];
        }
        break;
    case 1:
        if(s.top[1] == maxsize){
            printf("栈空\n");
            return -1;
        }
        else{
            return s.data[s.top[1]++];
        }
        break;
    }
}

7、数据结构–链表合并

7、假设有两个按元素值递增排序的线性表,均已单链表项式存储,请编写算法将这两个单链表合并为一个按元素值递减排序的

单链表,并要求利用远来两个单链表的结点存放归并后的单链表。

# include<stdio.h>

//单链表的定义
typedef struct LNode {
	ELemType data;
	LNode *next;
} LNode,*LinkList;

/*

解题思路:假设A,B带有头指针,定义pa,pb指针分别指向A,B的下一个结点,
在定义一个r指针,指向 pa/pb的下一个结点,防止断链
把从新排序的结点存放到A中,
运用头插法,先将A,B中较小的元素插入A中,实现整体按元素值递减有序;
因为A,B链表中的结点个数不一样,
所以当A中的结点数更少时 ,将B中的元素依次加入A中
反之,则将A中的元素依次加入C中
*/
LinkList Merge(LNode &A,LNode &B) {
	LNode *pa = A->next;
	LNode *pb = B->next;
	LNode *r;     		// 标记指针,防止断链,指向 pa/pb的下一个结点
	A->next == NULL;    // 将原来的A链表置空,用来存储从新组合的链表 C

	while(pa&&pb) {   //
		if(pa->data <= pb->data) { // 运用头插法将大的元素率先加入C链表中
			r = pa->next;
			pa->next = A->next;
			A->next = pa;
			pa = r;
		} else {
			r = pb->next;
			pb->next = A->next;
			A->next = pb;
			pb = r;
		}
	}
	if(pa) {
		pb = pa;
	}
	while(pb) {
		r = pb->next;
		pb->next = A->next;
		A->next = pb;
		pb = r;
	}
	free(B);
}

8、数据结构–二叉树

8、假设一个仅包含二元运算符的算术表达式以链表形式存储在二叉树BT中,写出计算该算术表达式值的算法

/*
解题思路:利用递归思想
利用二叉树的后续遍历进行改造
先计算出左子树的值,然后再算出右子树的值,最后再根据根节点的符号求出最终值
树的结构体中添加运算符和运算值
*/


typedef struct BiNode{
    int data;   // 数值
    int value;	// 运算值
    char opt;	// 操作符
    struct BiNode *lchild,*rchild;		// 左右子树
}*BiTree,BiNode;

//对二叉链表树中的结点计算
int Calculate(BiTree Bt){    
	int val_l, val_r;        
	if(Bt!=NULL){
		val_l = Calculate(Bt->lchild);    //递归计算左、右子树
		val_r = Calculate(Bt->rchild);
		switch(Bt->opt){        //根据根节点的字符将左右子结果计算为当前这一层子树的结果
			case'+':
				Bt->value = val_l + val_r;
				break;
			case'-':
				Bt->value = val_l - val_r;
				break;
			case'*':
				Bt->value = val_l * val_r;
				break;
			case'/':
				Bt->value = val_l / val_r;
				break;
			default:
				break;
		}
	}
	return Bt->value;
}

9、数据结构–图

9、已知一个无向图,要分别用 Prim 和 Kruskal 算法生成最小树(假设以①为起点,试画出构造过程)。

10、数据结构–森林转二叉树

10、森林转二叉树
请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XUN~MLF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值