C语言必做练习题(附带源代码与运行截图)

1.创建一个链表并反向输出
思路:双向链表反向输出

#include<stdio.h>
#include<stdlib.h>
struct list
{
	int date;
	struct list *prve,*next;
};
int main()
{   
	struct list* head, *before, * end;
	head = (struct list*)malloc(sizeof(struct list));
	head->next = NULL;
	head->prve = NULL;
	before = end = head;
	printf("创建一个1-10的数列并反向输出");
	for (int i = 1; i <= 10; i++)
	{
		end = (struct list*)malloc(sizeof(struct list));
		end->date = i;
		end->next = NULL;
		end->prve = before;
		before->next = end;
		before = end;
	}
	struct list* t = end;

	while (t->prve)
	{
		printf("%d ", t->date);
		t = t->prve;
	}
	return 0;
}

在这里插入图片描述
2.设计函数实现任意数制转化
设计2-36进制相互转化
利用字符串存储数据,将a进制转化为10进制再转化为b进制
a进制转化10进制过程每次取余乘权数直到为0
10进制转化b进制为取余除b直到为0

#include<stdio.h>
#include<string.h>
int toten(int t,int a)
{
	int ans = 0,to=1;
	while (t)
	{
		ans += (t % 10) * to;
		to = to * a;
		t = t / 10;
	}
	return ans;
}
char* tob(int ten, int b)
{
	char character[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	static char ans[32];
	int i;
	if (ten < b)
	{
		ans[0] = character[ten];
	}
	else
	{
		for ( i = 0; ten; i++)
		{
			ans[i] = character[(ten % b)];
			ten /= b;
		}
		ans[i] = '\0';
	}
	return ans;
}
int main()
{   
	int a, b,t;
	printf("请输入a进制及a进制数与要转化的b进制:\n");
	scanf("%d%d%d", &a, &t, &b);
	printf("%d进制数%d转化为10进制结果为:%d\n", a,t,toten(t, a));
	char *c;
	printf("%d进制数%d转化为%d进制结果为:", a, t);
	c = tob(toten(t, a), b);
	for (int i = strlen(c); i >= 0; i--)
		printf("%c", c[i]);
	return 0;
}

在这里插入图片描述
3.设计一个函数放回字符串最后一个字符若为空放回NULL;
利用该函数放回两个字符串的最后一个字符,用指针完成;

#include<stdio.h>
#include<string.h>
char lastchar(char str[])
{
	if (strlen(str) == 0)return '\0';
	return str[strlen(str)-1];
}
int main()
{    
	char a[100] = { "heajdskjal" };
	char b[100] = { "" };
	printf("%c\n", lastchar(b));
	printf("%c", lastchar(a));
	return 0;
}


4.输入三个数字,利用指针找出最大最小值
分析:p,q,r分别指向a,b,c;
如果a<b让q指向p,p指向b的地址完成交换,反之不变 此次if后保证p指向a,b最大值同理比较c
最后q,r为三个数中较小的两个数一次比较可以得到最小值;

#include<stdio.h>
int main()
{
	int a, b, c;
	int* p, * q, * r;
	p = &a, q = &b, r = &c;
	printf("输入三个数字\n");
	scanf("%d%d%d", &a, &b, &c);
	if (*p < *q) 
	{
		q = p;
		p = &b;
	}
	if (*p < *r)
	{
		r = p;
		p = &c;
	}
	if (*q <* r)
	{
		r = q;
	}
	printf("最大值为:%d\n最小值为%d\n", *p, *r);
	return 0;
}

在这里插入图片描述
5.给定一个年份 y 和一个整数 d,问这一年的第 d 天是几月几日?注意闰年的 2 月有29 天。
分析:利用数组存储月份天数,判断是否为闰年;
循环减得到月份和天数;

#include<stdio.h>
int month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
void run(int year)
{
	if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
		month[2] = 29;
	else month[2] = 28;
}
int main()
{
	int year,day;
	printf("请输入你需要查询的年份以及天数");
	scanf("%d%d", &year, &day);
	run(year);
	int i;
	for (i= 1; i <= 12&&day-month[i]>0; i++)
	{
		day -= month[i];
	}
	printf("查询日期为:%d月%d日", i, day);
	return 0;
}
  1. 用指针实现:程序的功能是在字符串 s 中找出最大的字符并放在第一个位置上,并将该字符前的原字符往后顺序移动。
    分析:简单模拟,找到最大字符记录其位置
#include<stdio.h>
#include<string.h>
int main()
{
	char str[100];
	printf("输入字符串:");
	scanf("%s", str);
	char* t=&str[0];
	int i,j=0;
	for ( i = 0; i < strlen(str); i++)
	{
		if (*t < str[i])
		{
			t = &str[i];
			j = i;
		}
	}
	str[0] = *t;
	printf("修改后字符串为:\n");
	for (int i = j; i > 1; i--)
	{
		str[i] = str[i - 1];
	}
	printf("%s", str);
	return 0;
}
  1. 用指针实现删除字符串 s 中的所有空格(包括 TAB 符、回车符)
#include<stdio.h>
#include<string.h>
int main()
{  
	char str[100],ans[100];
	printf("输入一个字符串");
	scanf("%[^\n]", str);
	char* t = &str[0];
	int i,j=0;
	for (i = 0; i < strlen(str); i++,t++)
	{
		if (*t ==' ')continue;
		else ans[j++] = *t;
	}
	ans[j] = '\0';
	printf("去空格后:");
	for ( j = 0; j < strlen(ans); j++)
		printf("%c", ans[j]);;
	return 0;
}
  1. 求数组的最大值和最小值,并分析时间复杂度和空间复杂度。
#include<stdio.h>
int main()
{  
	int num[100] = {32,21,41,12,3,34,5,77};
	int max = num[0], min = num[0];
	for (int i = 0; i <= 7; i++)
	{
		if (max < num[i])max = num[i];
		if (min > num[i])min = num[i];
	}
	printf("最大值为:%d 最小值为:%d", max, min);
	return 0;
}

时间复杂度:历遍数组时间复杂度为O(n);
空间复制度为数组大小S(n)=O(n);
12. 通过函数交换 a 和 b 的值,并详细分析内存里的数值``的传输过程。

#include<stdio.h>
void swap(int* t1, int* t2)
{
	int t;
	t = *t1;
	*t1 = *t2;
	*t2 = t;
}
int main()
{  
	int a = 1, b = 2;
	swap(&a, &b);
	printf("a的值:%d b的值:%d",a,b);
	return 0;
}

将a,b地址作为函数参数利用临时变量t存储a地址中的值
将b地址中的值赋给a地址中的值;
再将变量t值赋给b地址中的值;
13. 利用递归函数调用方式,将所输入的 5 个字符,以相反顺序打印出来。

#include<stdio.h>
void f(int n)
{
	if (n == 1)
	{
		char x=getchar();
		putchar(x);
	}
	else
	{
		char x = getchar();
		f(n - 1);
		putchar(x);
	}
}
int main()
{  
	printf("输入五个字符");
	f(5);
	return 0;
}
  1. 创建两个学生链表,分别根据学生成绩对链表排序,并把这两个链表连接在一起。连接的时候,按照从小到大的顺序连接。
    分析:链表基本操作
#include<stdio.h>
#include<stdlib.h>
struct node
{
	int socre;
	struct node *next;
};
void creat(struct node* head)
{
	struct node* before, * temp;
	before = temp = head;
	for (int i = 0; i < 5; i++)
	{
		temp = (struct node*)malloc(sizeof(struct node));
		scanf("%d", &temp->socre);
		temp->next = NULL;
		before->next = temp;
		before = temp;
	}
}
void sort(struct node* head)
{
	struct node* begin = NULL, * end = NULL;
	begin = head->next;
	while (begin != end)
	{
		while (begin->next != end)
		{
			if (begin->socre > begin->next->socre)
			{
				int t;
				t = begin->socre;
				begin->socre = begin->next->socre;
				begin->next->socre = t;
			}
			begin = begin->next;
		}
		end = begin;
		begin = head->next;
	}
}
void connct(struct node*head,struct node* head1, struct node* head2)
{
	struct node* t1,*t2;
	t1 = head1->next;
	t2 = head2->next;
	struct node* before, * temp;
	before = temp = head;
	while(t1&&t2)
	{
		temp = (struct node*)malloc(sizeof(struct node));
		if (t1->socre < t2->socre) { temp->socre = t1->socre; t1 = t1->next; }
		else { temp->socre = t2->socre; t2 = t2->next; }
		temp->next = NULL;
		before->next = temp;
		before = temp;
	}
	while (t1)
	{
		temp = (struct node*)malloc(sizeof(struct node));
		 temp->socre = t1->socre; t1 = t1->next; 
		temp->next = NULL;
		before->next = temp;
		before = temp;
	}
	while (t2)
	{
		temp = (struct node*)malloc(sizeof(struct node));
		temp->socre = t2->socre; t2 = t2->next;
		temp->next = NULL;
		before->next = temp;
		before = temp;
	}
}
void dis(struct node* head)
{
	struct node* t = head->next;
	while (t)
	{
		printf("%d ", t->socre);
		t = t->next;
	}
	printf("\n");
}
int main()
{  
	struct node* head1, * head2, * head3;
	head1 = (struct node*)malloc(sizeof(struct node));
	head1->next = NULL;
	creat(head1);
	sort(head1);
	printf("对第一个链表排序后:\n");
	dis(head1);
	head2 = (struct node*)malloc(sizeof(struct node));
	head2->next = NULL;
	creat(head2);
	sort(head2);
	printf("对第二个链表排序后:\n");
	dis(head2);
	printf("链接两个链表\n");
	head3 = (struct node*)malloc(sizeof(struct node));
	head3->next = NULL;
	connct(head3, head1, head2);
	dis(head3);
	return 0;
}

在这里插入图片描述
16. 有 n 个整数,使其前面各数顺序向后移 m 个位置,最后 m 个数变成最前面的 m
个数。

#include<stdio.h>
int main()
{
	int num[100];
	int n, m;
	printf("请输入n");
	scanf("%d", &n);
	printf("请输入n长度的数组");
	for (int i = 1; i <= n; i++)
		scanf("%d", &num[i]);
	printf("请输入往后移动的位数m");
	scanf("%d", &m);
	for (int i = n + m; i >=n-1; i--)
	{
		num[i] = num[i - m];
	}
	for (int j = 1, i = n+1; j <=m; i++, j++)
	{
	num[j] = num[i];
	}
	for (int i = 1; i <= n + m; i++)
		printf("%d ", num[i]);
	return 0;
}
  1. 将一个正整数分解质因数。例如:输入 90,打印出 90=233*5。
#include<stdio.h>
int main()
{
	int n;
	printf("请输入一个正整数:");
	scanf("%d", &n);
	printf("%d = ", n);
	for (int i = 2; i <= n; i++)
	{   
		if (n % i == 0)
		{
			while (n % i == 0)
			{
				printf("%d", i);
				n /= i;
				if (n >=i)printf("*");
			}
		}
	}
	if(n>1)printf("%d\n", n);
	
	return 0;
}

  1. 给定 n 个正整数,找出它们中出现次数最多的数。如果这样的数有多个,请输出其中最小的一个
    分析:桶排序
#include<stdio.h>
int book[100];
int main()
{
	
	int n;
	printf("输入n:");
	scanf("%d", &n);
	int t;
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &t);
		book[t]++;
	}
	int max =-1, posi=0;
	for (int i = 1; i <= 100; i++)
	{
		if (book[i] > max)
		{
			max = book[i];
			posi = i;
		}
	}
	printf("%d出现的最多", posi);
	return 0;
}
  1. 求 0-7 所能组成的奇数个数。
    分析:排列组合问题
#include<stdio.h>
int  main()
{
	long sum = 4, t = 4;     //1位数为4个 
	int j;
	for (j = 2; j <= 8; j++)
	{
		printf("\n%ld", sum);
		if (j <= 2)             //如果j为两位数 
			t *= 7;
		else
			t*= 8;
		sum += t;
	}
	printf("\nsum=%ld", sum);
}

  1. 把 M 个同样的苹果放在 N 个同样的盘子里,允许有的盘子空着不放,问共有多
    少种不同的分法?(用 K 表示)5,1,1 和 1,5,1 是同一种分法。
    m<n时,至少有n-m个盘子空着(这些空盘子并不影响最后的结果,因为每种方法都带有着些空盘子)。只考虑m个苹果放m个盘子 f(m,n)=f(m,m)

m>n时,按是否有空盘子 分2种情况:
a.假设至少一个盘子空着,相当于f(m,n)=f(m,n-1)
b.所有的盘子都有苹果,假设每个盘子可以先放一个,问题就变成:m-n个苹果放到n个盘子,即f(m,n)=f(m-n,n)
临界条件

n=1时,所有苹果都放在同一个盘子里 f(m,n)=1
m=0时,没有苹果 f(m,n)=1

#include<stdio.h>
int  apple(int m, int n) {
	if (n == 1 || m == 0)  return 1;
	else if (m < n) return apple(m, m);
	else 			return apple(m, n - 1) + apple(m - n, n);
}
int  main()
{
	int m, n;
	printf("输入苹果个数和盘子个数");
	scanf("%d%d", &m, &n);
	int k = apple(m,n);
	printf("有%d种放法", k);
}
  1. 有一实数或者字母序列 A[1]、A[2] 、A[3] 、……A[n-1] 、A[n],若 i<j,并且 A[i]
    >A[j],则称 A[i]与 A[j]构成了一个逆序对,求字符串 A 中逆序对的个数。
    分析:归并排序求逆序对
#include<stdio.h>
int num[100005], tem[100005];
long long sort(int l, int r)
{
    long long res;
    if (l == r)return 0;
    int mid;
    mid = l + r >> 1;
    res = sort(l, mid) + sort(mid + 1, r);
    int i = l, j = mid + 1, k = 0;
    while (i <= mid && j <= r)
    {
        if (num[i] <= num[j])tem[k++] = num[i++];
        else { tem[k++] = num[j++]; res += mid - i + 1; }

    }
    while (i <= mid)tem[k++] = num[i++];
    while (j <= r)tem[k++] = num[j++];
    for (int i = l, j = 0; i <= r; i++, j++)
        num[i] = tem[j];
    return res;
}
int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
        scanf("%d", &num[i]);
    printf("%lld", sort(0, n - 1));
    return 0;
}
  1. 给一个非负整数,判断这个数是不是相互不同的非负整数的阶乘的和。如 6=3!;7=3!+ 1!;但 5 不是相互不同的非负整数的阶乘的和。
#include<stdio.h>
int jc(int n)
{
	if (n == 1)return 1;
	else return n * jc(n - 1);
}
int main()
{
	int num[11] = {0};
	for (int i = 1; i <= 10; i++)
	{
		num[i] = jc(i);
	}
	int n;
	printf("请输入一个数");
	scanf("%d", &n);
		if (n == 0)printf("NO\n");
		else
		{
			for (int i = 9; i >= 1; i--)
			{
				if (n >= num[i])n = n - num[i];
			}
			if (n == 0)printf("YES");
			else printf("NO");
		}
		return 0;
}
  1. 图像的像素可以用一个二维数组来表示,对图像求中值滤波,滤波窗口大小为 3x3。图像像素值自行设定。
    分析:二维状态压缩为一维,排序找中间值
#include<stdio.h>
int GetMedNum(int* Array, int iFilterLen)
{
	int i, j;
	int  Temp;

	for (j = 0; j < iFilterLen - 1; j++)
	{
		for (i = 0; i < iFilterLen - j - 1; i++)
		{
			if (Array[i] > Array[i + 1])
			{
				Temp = Array[i];
				Array[i] = Array[i + 1];
				Array[i + 1] = Temp;
			}
		}
	}
	Temp = Array[(iFilterLen + 1) / 2];

	return Temp;
}
int main()
{
	int num[3][3] = { 1,23,43,534,213,11,55,77,44 };
	int t[9];
	int k = 0;
	for(int i=0;i<3;i++)
		for (int j = 0; j < 3; j++)
		{
			t[k++] = num[i][j];
	    }
	printf("%d", GetMedNum(t, 9));
}
  1. 在图像编码的算法中,需要将一个给定的方形矩阵进行 Z 字形扫描(Zigzag Scan)。
    给定一个 n×n 的矩阵,Z 字形扫描的过程如下图所示:
    对于下面的 4×4 的矩阵,
    1 5 3 9
    3 7 5 6
    9 4 6 4
    7 3 1 3
    对其进行 Z 字形扫描后得到长度为 16 的序列:
    1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3
    请实现一个 Z 字形扫描的程序,给定一个 n×n 的矩阵,输出对这个矩阵进行 Z 字形扫描的结果。
#include<stdio.h>
int num[100][100];
int main()
{  
	int n;
	printf("请输入矩阵边长");
	scanf("%d", &n);
	int i, j;
	printf("输入矩阵数据\n");
	for (i = 0; i < n; i++)
		for (j = 0; j < n; j++)
			scanf("%d", &num[i][j]);
	i = 0,j=0;
	int k = 1;
	printf("%d ", num[0][0]);
	while (k<=n*n)
	{
		if (j + 1 >= n)
		{
			i++;
		}
		else
		{
			j++;
		}
		if (k++ >= n * n)break;
		printf("%d ", num[i][j]);
		
		while (j-1>= 0&&i+1<n) //斜下
		{
			i++, j--; printf("%d ", num[i][j]);
			k++;
		}
		if (i + 1 >= n)
		{
			j++;
		}
		else
		{
			i++;
		}
		if (k++ >= n * n)break;
		printf("%d ", num[i][j]);
		
		while (i -1>=0&&j+1<n) //斜上
		{
			i--, j++; 
			printf("%d ", num[i][j]);
			if (k++ >= n * n)break;
		}
		
	}
	return 0;
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值