当前位置:网站首页>關於一道教材題的講解

關於一道教材題的講解

2022-06-25 13:17:00 LIn_jt

關於一道教材題的講解

前幾天上機實驗時,做了一道這樣的題,感覺還是蠻有趣的,如下所示
在這裏插入圖片描述

也是引發了自己一點小小的思考,以下是我自己的圖解:>

#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;
}



原网站

版权声明
本文为[LIn_jt]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/176/202206251235204486.html