C语言题目练习

目录

前言

杨氏矩阵查找某一个数的位置

方法一:遍历

方法二:比较右上角

方法三:二分法查找

结语


前言

        纸上得来终觉浅,觉知此事要躬行。C语言的学习不仅要了解理论知识,更要不断练习,在练习中成长。下面我将给出几到例题,并分析讲解,帮助我们在实践中了解C语言。

杨氏矩阵查找某一个数的位置

        如果一个矩阵的每行从左到右递增,从上到下递增,那么这个矩阵就叫做杨氏矩阵。可以类比我们已知的递增数列,只不过杨氏矩阵是一个二维的数组罢了。

        例如:              

        像这样的矩阵就都是杨氏矩阵。

        那么对于杨氏矩阵,我们如何去找出它其中的某一个数呢(如果没有就输出找不到)

方法一:遍历

        对于一个数组,我们只需要对它其中的每一个数都判断一次,看是否是我要找的数,就能知道该数是否在数组中,在哪个位置。

        但此方法效率太低,我们可以稍微利用杨氏矩阵的特点,降低查找难度。

方法二:比较右上角

        对于杨氏矩阵,取出它右上角的数字,那么这个数字就是这一行最大的,这一列最小的。然后我们拿我们要找的数字跟它进行比较的话,如果我们要找的数比它大,那么可以明确,对于最上面一行来说,肯定找不到我们要找的数字;反之,如果我们要找的数比这个小,那么就可以肯定,对于最右边那一列数字,都肯定找不到我们要找的数字。因此,无论比较结果是什么,我们都可以排除掉一行的数据,那样就大大减小了寻找成本,提高了查找效率。

        代码实现:

#include <stdio.h>

struct point		//定义结构体用来存放返回坐标
{
	int x;
	int y;
}p;

struct point find_num(int arr[3][3], int r, int c, int k)  //寻找函数
{
	int x = 0;
	int y = c - 1;
	struct point p = { -1,-1 };
	while ((x <= r - 1) && (y >= 0))
	{
		if (k < arr[x][y])
		{
			y--;
		}
		if (k > arr[x][y])
		{
			x++;
		}
		if (k == arr[x][y])
		{
			p.x = x+1;
			p.y = y+1;
			return p;
		}
	}
    return p;
}

int main()
{
	int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
	int k = 0;				//要找的数字
	scanf("%d", &k);		//输入要找的数字
	struct point f = find_num(arr, 3, 3, k); //寻找函数,找到返回坐标,找不到返回(-1,-1)。输入参数是被寻找数组地址;数组行列数;要寻找的数字。

	printf("%d %d", f.x, f.y);	//打印坐标。

	return 0;
}

效果:

        我们创建了一个结构体变量来存放坐标,如果找到则返回目标数的坐标,如果找不到则返回:-1 -1。可以看到我们成功实现了该功能简化了计算。

        那么,还有什么方法可以用来查找吗,我想到了:二分法。

方法三:二分法查找

        对于一个杨氏矩阵,我们可以发现这样一个规律,对于里面任意一个位置的数字A来说,它左上角的数肯定都比它小;它右下角的数肯定都比他大;但是剩余部分的数字和A的关系都不确定。我们利用这个特性,进行一个查找。

        大致思路是,先设定两个边界,初始为矩阵第一个和最后一个数的坐标。然后选定其中点坐标,假设为上图A点,然后判断目标值和A的大小,如果比A小,那肯定在A的左上方,那么新的右边界可以设置为A;如果比A大,那要分情况判断,因为有两个不确定的区域。因此我们先判断目标点和C的关系,如果比C小,那么可以确定目标点所在区域为如图的右上块区域,可以设置左边界为A点对应列的第一个元素坐标为新的左边界,C点为新的右边界;如果比C大,那就排除了右上块区域的可能。那我们再去判断B点,如果目标点比B小,则目标点只能在左下块,此时设定A点对应行的第一个元素为新的左边界,B点为右边界;如果比B大,那就排除了左下块的可能性,那目标值只可能在右下区域,于是我们设置A为新的左边界,右边界不变。

        流程图如下:

        程序实现可以大家自己动手尝试一下,这个查找效率理论上是比上一种更高的。程序我会后续补上。

结语

        感谢大家的阅读,如果对你有帮助我会很开心。

        还是那句话:每天保持练习,持之以恒,我们的C语言技术才会越发熟练,不要小瞧每一次练习。

  • 39
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

彭逍遥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值