題目描述
在一個二維數組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。
分析:
1 | 2 | 8 | 9 |
---|---|---|---|
2 | 4 | 9 | 12 |
4 | 7 | 10 | 13 |
6 | 8 | 11 | 15 |
從二維數組最右上角的數值(9)開始比較,若目標比該數大,則目標肯定在該數的下方,反之,在該數的左方。根據此規則,尋找下一個比較的數值,重複以上規則,直到找到目標數,或者數組越界。
//
// main.c
// func
//
// Created by 52coder on 2017/12/18.
// Copyright © 2017年 52coder. All rights reserved.
//
#include <stdio.h>
int Find(int matrix[],int rows,int columns,int number)
{
if((NULL != matrix )&&(rows > 0)&&(columns > 0))
{
int row = 0;
int col = columns - 1;
while((row < rows)&&(col >= 0))
{
if(matrix[row * columns + col] == number)
{
return 1;
}
else if(matrix[row * columns + col] > number)
{
col = col - 1;
}
else
{
row = row + 1;
}
}
}
return 0;
}
int search(int (*matrix)[4],int rows,int columns,int number)
{
if((NULL != matrix )&&(rows > 0)&&(columns > 0))
{
int row = 0;
int col = columns - 1;
while((row < rows)&&(col >= 0))
{
if(matrix[row][col] == number)
{
return 1;
}
else if(matrix[row][col] > number)
{
col = col - 1;
}
else
{
row = row + 1;
}
}
}
return 0;
}
int main(int argc, const char * argv[])
{
int a[16]={1,2,8,9,2,4,9,12,4,7,10,13,6,8,11,15};
printf("%d\n",Find(a, 4, 4, 7));
int b[4][4]={1,2,8,9,2,4,9,12,4,7,10,13,6,8,11,15};
printf("%d\n",search(b, 4, 4, 7));
return 0;
}
上面的代碼中提供了兩種解決問題的方法,第一種是按照一維數組的形式所寫,書中給出的答案如此,那麼如何用二維數組的形式傳參呢?
最近剛好在看《C語言程序設計》大名鼎鼎的K&&R,其中有如下介紹,可以參考文章C語言拾遺閱讀全部讀書筆記。
daytab[2][13]={
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
}
如果將二維數組作爲參數傳遞給函數,那麼函數的參數聲明中必須指明數組的列數。數組的行數沒有太大關係,函數調用時傳遞的是一個指針,它指向由行向量構成的一維數組,其中每個行向量是具有13個整型元素的一維數組,
在該例子中,傳遞給函數的是一個指向很多對象的指針,其中每個對象是由13個整型元素構成的一維數組。因此,如果將數組daytab作爲參數傳遞給函數f,那麼f的聲明應該寫成如下形式:
f(int daytab[2][13]){……}
也可以寫成
f(int daytab[][13]){……}
由於數組的行數無關緊要,所以該聲明還可以寫成:
f(int (*daytab)[13]){……}
這種聲明形式表明參數是一個指針,它指向具有13個整型元素的一維數組。因爲方括號[]的優先級高於*的優先級,所以上述聲明中必須使用圓括號,如果去掉圓括號
int *daytab[13]
則變成聲明一個數組,該數組有13個元素,其中每個元素都是一個指向整型對象的指針。一般來說,除數組的第一維可以不指定大小外,其餘各維必須明確指定大小。