关于一道教材题的讲解

关于一道教材题的讲解

前几天上机实验时,做了一道这样的题,感觉还是蛮有趣的,如下所示
在这里插入图片描述

也是引发了自己一点小小的思考,以下是我自己的图解:>

#define ROW 4

#define COL 4


int main()
{
	int arr[ROW][COL];
	int bigger[ROW];//用来储存每一行的最大值.
	int putcol[ROW];//用来储存最大值的行数
	int putrow[ROW];//用来储存最大值的列数
	int tmp1 = 0;//用来获取一行中最大值的那个列数
	int tmp2 = 0;//用来获取一行中最大值的那个行数
	int i = 0;
	int j = 0;
	int max = 0;//获取每一行中的最大值.
	int count = 0;//用来判断当这个二维数组没有鞍点.
	int flag = 1;//用来判断这个二维数组有鞍点

	//初始化二维数组
	for (i = 0; i < ROW; i++)
	{
		for (j = 0; j < COL; j++)
		{
			scanf("%d", &arr[i][j]);
		}
	}

	//获取每一行的最大值,所在的列数,所在的行数,并将其储存
	for (i = 0; i < ROW; i++)
	{
		max = arr[i][0];
		for (j = 0; j < COL; j++)
		{
			if (max < arr[i][j])
			{
				max = arr[i][j];
				tmp1 = j;
			}
		}
		bigger[i] = max;
		putcol[i] = tmp1;
		putrow[i] = i;
	}

	//用来判断这个点是不是鞍点,因为我们刚才已经按照顺序存储了每一行中最大值的列数,将其与那一列的每一个值进行比较。
	//第一层for循环是循环每一个最大值的.
	for (i = 0; i < ROW; i++)
	{
		max = bigger[i];
		tmp1 = putcol[i];
		tmp2 = putrow[i];
		flag = 1;//用来判断每一行中的最大值是不是鞍点
		for (j = 0; j < ROW; j++)
		{
			if (max == arr[j][tmp1])// 因为要比较那一列的每一个数,因此难免会与其自身进行比较,因此,当这两个数相等的时候,就什么都不做。
			{
				;
			}
			if (max > arr[j][tmp1])
			{
				flag = 0;//一列中只要有比max还小的值,证明其一定不是鞍点,直接跳出内层循环
				break;
			}
			if(max < arr[j][tmp1])
			{
				flag = 1;//当每一行中的最大值都是其列上的最小值时,flag为1,证明其有鞍点
			}
		}
		if (flag == 1)
		{
			count = 1;//有鞍点,令count = 1;没有鞍点的话,count就为0,下面可以直接打印
			printf("该二维数组有鞍点\n行数为:>%d\n列数为:%d\n", putrow[i], putcol[i]);
		}
	}
	if (count == 0)
	{
		printf("该二维数组没有鞍点\n");
	}

	return 0;
}

首先阐明以下自己的思路,对于本题,我是这样想的,首先求出每一行的最大值,也就是这样子:

在这里插入图片描述

然后,我将这三个数放到我们创建的bigger[]数组中,用来对后续其与整列的比较

不仅如此,我还将最大值的列记录下来,放到我们创建的putcol数组中,也是以便用来对后续其一列中的比较。
在这里插入图片描述

那么我们为什么要创建putrow数组呢,其实也只是为了方便后面保存并展开循环罢了,因为一行中只有一个最大值,而行的数ROW

由我们界定,因此putrow数组也即为每一行的数字.

我们设置出flag是为了记录此时每一行的最大值是否是鞍点,如果是的话我们赋值为1,如果不是的话我们赋值其为0.

count也是同样道理,如果最终count = 0的话,证明数组没有鞍点,因此我们按照题目要求输出其没有鞍点即可

思路讲完了,现在来讲一下代码是如何实现的。首先是输入部分

在这里插入图片描述

因为设定二维数组,所以需要一个嵌套循环来实现初始化部分,如上图所示。

接下来是重点部分,也即求每一行中的最大值,我们先把max赋值为每一行的第一个数,让其与每一行中的每一个数来进行比较,同时,在求出最大值的时候,记录列数的值在这里插入图片描述

记录到每一行的最大值后,我们将其存储到我们的数组里面去,也即

将max的值存储到bigger数组,将此时最大值的列数存储的putcol数组,将此时的行数存储到putrow数组,为我们后续比大小提供了一定的铺垫。

这些条件准备好之后,也即我们接下来的每一列比大小部分,我是这样子做的
在这里插入图片描述

外面一层循环是用来刚才将我们每一行存储的最大值拿出来,里层循环是用来把最大值与那一列的数进行比较,要注意的是,如果max已经比其中一列数大了,那么我们可以直接跳出循环,并且令flag = 0;也即该数不是鞍点。

还有就是,我们与那一列的每一个数进行比较,也就会让它与其本身进行比较,因此,当这个数与其自身进行比较时,我们什么也不干

程序运行的结果为:
在这里插入图片描述

在这里插入图片描述

下面是对程序进行的改进:

要是在每一行求出的最大值中,在那一列上有与其相等的数呢?,这个时候并不满足鞍点的定义,同时,我认为在其有鞍点的时候令flag = 1 是对余的,因此,我们对程序进行以下改进:

在这里插入图片描述

可以看到的是,我对几处进行了改动:
在这里插入图片描述

我们知道,当每一行的最大值与其进行比较时,会与它自身进行比较,但我们要怎么区分是他本身,还是与它相等但不同行的数呢?,我们刚才已经将其行号存储到putrow数组中,并且率先将tmp2里面的值放置了其行号,因此,我们可以将行号进行比较,如果行号相同,那么也即为自己与其本身进行比较,我们什么也不干

在这里插入图片描述

这里将每一行的最大值与其每一列的数进行比较,如果有两个数相等并且这两个数在不同的行号,那么这个数必然不是鞍点

如果大家对代码有什么改进的建议欢迎提出噢!!
下面是改进后的源代码

#define ROW 3

#define COL 4


int main()
{
	int arr[ROW][COL];
	int bigger[ROW];//用来储存每一行的最大值.
	int putcol[ROW];//用来储存最大值的行数
	int putrow[ROW];//用来储存最大值的列数
	int tmp1 = 0;//用来获取一行中最大值的那个列数
	int tmp2 = 0;//用来获取一行中最大值的那个行数
	int i = 0;
	int j = 0;
	int max = 0;//获取每一行中的最大值.
	int count = 0;//用来判断当这个二维数组没有鞍点.
	int flag = 1;//用来判断这个二维数组有鞍点

	//初始化二维数组
	for (i = 0; i < ROW; i++)
	{
		for (j = 0; j < COL; j++)
		{
			scanf("%d", &arr[i][j]);
		}
	}

	//获取每一行的最大值,所在的列数,所在的行数,并将其储存
	for (i = 0; i < ROW; i++)
	{
		max = arr[i][0];
		for (j = 0; j < COL; j++)
		{
			if (max < arr[i][j])
			{
				max = arr[i][j];
				tmp1 = j;
			}
		}
		bigger[i] = max;
		putcol[i] = tmp1;
		putrow[i] = i;
	}

	用来判断这个点是不是鞍点,因为我们刚才已经按照顺序存储了每一行中最大值的列数,将其与那一列的每一个值进行比较。
	//第一层for循环是循环每一个最大值的.
	for (i = 0; i < ROW; i++)
	{
		max = bigger[i];
		tmp1 = putcol[i];
		tmp2 = putrow[i];
		flag = 1;//用来判断每一行中的最大值是不是鞍点
		for (j = 0; j < ROW; j++)
		{
			if (max == arr[j][tmp1] && j == tmp2)// 因为要比较那一列的每一个数,因此难免会与其自身进行比较,因此,当这两个数相等的时候,就什么都不做。
			{
				;
			}
			if (max >= arr[j][tmp1]&& j!=tmp2)
			{
				flag = 0;//一列中只要有比max还小的值,证明其一定不是鞍点,直接跳出内层循环
				break;
			}
			if (max < arr[j][tmp1])
			{
				flag = 1;//当每一行中的最大值都是其列上的最小值时,flag为1,证明其有鞍点
			}
		}
		if (flag == 1)
		{
			count = 1;//有鞍点,令count = 1;没有鞍点的话,count就为0,下面可以直接打印
			printf("该二维数组有鞍点\n行数为:>%d\n列数为:%d\n", putrow[i], putcol[i]);
		}
	}
	if (count == 0)
	{
		printf("该二维数组没有鞍点\n");
	}

	return 0;
}



  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值