二维数组的查找

题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。


       当我们需要解决一个复杂的问题时,一个很有效的办法就是从一个具体的问题入手,通过分析简单具体的例子,试图寻找普遍的规律。针对这个问题,我们不妨也从一个具体的例子入手。下面我们以在题目中给出的数组中查找数字7为例来一步步分析查找的过程。

       我们发现如下规律:首先选取数组中右上角的数字。如果该数字等于要查找的数字,查找过程结束;如果该数字大于要查找的数字,剔除这个数字所在的列;如果该 数字小于要查找的数字,剔除这个数字所在的行。也就是说如果要查找的数字不在数组的右上角,则每一次都在数组的查找范围中剔除一行或者一列,这样每一步都 可以缩小查找的范围,直到找到要查找的数字,或者查找范围为空。

     

      把整个查找过程分析清楚之后,我们再写代码就不是一件很难的事情了。下面是上述思路对应的参考代码:

  1. bool Find(int* matrix, int rows, int columns, int number)  
  2. {  
  3.     bool found = false;  
  4.   
  5.     if(matrix != NULL && rows > 0 && columns > 0)  
  6.     {  
  7.         int row = 0;  
  8.         int column = columns - 1;  
  9.         while(row < rows && column >=0)  
  10.         {  
  11.             if(matrix[row * columns + column] == number)  
  12.             {  
  13.                 found = true;  
  14.                 break;  
  15.             }  
  16.             else if(matrix[row * columns + column] > number)  
  17.                 -- column;  
  18.             else  
  19.                 ++ row;  
  20.         }  
  21.     }  
  22.   
  23.     return found;  
  24. }  

 

       在前面的分析中,我们每一次都是选取数组查找范围内的右上角数字。同样,我们也可以选取左下角的数字。感兴趣的读者不妨自己分析一下每次都选取左下角的查 找过程。但我们不能选择左上角或者右下角。以左上角为例,最初数字1位于初始数组的左上角,由于1小于7,那么7应该位于1的右边或者下边。此时我们既不 能从查找范围内剔除1所在的行,也不能剔除1所在的列,这样我们就无法缩小查找的范围。

二维数组的乘法实现可参考:http://www.cnblogs.com/heyonggang/p/3262069.html

实现代码如下:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 // 二维数组matrix中,每一行都从左到右递增排序,
 5 // 每一列都从上到下递增排序
 6 bool Find(int* matrix, int rows, int columns, int number)
 7 {
 8     bool found = false;
 9 
10     if(matrix != NULL && rows > 0 && columns > 0)
11     {
12         int row = 0;
13         int column = columns - 1;
14         while(row < rows && column >=0)
15         {
16             if(matrix[row * columns + column] == number)
17             {
18                 found = true;
19                 break;
20             }
21             else if(matrix[row * columns + column] > number)
22                 -- column;
23             else
24                 ++ row;
25         }
26     }
27 
28     return found;
29 }
30 
31 int main()
32 {
33     int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
34     bool result = Find((int*)matrix , 4 , 4 , 7); //这里实参是(int*)matrix
35     if(result == true)
36         printf("Passed.\n");
37     else
38         printf("Failed.\n");
39     return 0;
40 
41 }

 

 

测试代码如下:

    1. #include<iostream>  
    2. using namespace std;  
    3.   
    4.   
    5. // 二维数组matrix中,每一行都从左到右递增排序,  
    6. // 每一列都从上到下递增排序  
    7. bool Find(int* matrix, int rows, int columns, int number)  
    8. {  
    9.     bool found = false;  
    10.   
    11.     if(matrix != NULL && rows > 0 && columns > 0)  
    12.     {  
    13.         int row = 0;  
    14.         int column = columns - 1;  
    15.         while(row < rows && column >=0)  
    16.         {  
    17.             if(matrix[row * columns + column] == number)  
    18.             {  
    19.                 found = true;  
    20.                 break;  
    21.             }  
    22.             else if(matrix[row * columns + column] > number)  
    23.                 -- column;  
    24.             else  
    25.                 ++ row;  
    26.         }  
    27.     }  
    28.   
    29.     return found;  
    30. }  
    31.   
    32.   
    33. void Test(char* testName, int* matrix, int rows, int columns, int number)  
    34. {  
    35.     if(testName != NULL)  
    36.         printf("%s begins: ", testName);  
    37.   
    38.     bool result = Find(matrix, rows, columns, number);  
    39.     if(result == true)  
    40.         printf("Passed.\n");  
    41.     else  
    42.         printf("Failed.\n");  
    43. }  
    44.   
    45. // 要查找的数在数组中  
    46. void Test1()  
    47. {  
    48.     int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};  
    49.     Test("Test1", (int*)matrix, 4, 4, 7);  
    50. }  
    51.   
    52. // 要查找的数不在数组中  
    53. void Test2()  
    54. {  
    55.     int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};  
    56.     Test("Test2", (int*)matrix, 4, 4, 5);  
    57. }  
    58.   
    59.   
    60.   
    61. int main(int argc, char * argv[])  
    62. {  
    63.     Test1();  
    64.     Test2();  
    65.    
    66.     return 0;  
    67. }  
### C++ 二维数组 查找元素 遍历 示例 #### 1. 二维数组的定义与初始化 在C++中,可以使用静态或动态方式创建二维数组。以下是两种常见的声明方式: - **静态二维数组**: ```cpp int array[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} }; ``` - **动态二维数组**: ```cpp int rows = 3; int cols = 4; int** dynamicArray = new int*[rows]; for (int i = 0; i < rows; ++i) { dynamicArray[i] = new int[cols]; } // 初始化动态数组 for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols; ++j) { dynamicArray[i][j] = i * cols + j; } } ``` #### 2. 按行遍历二维数组 按照行优先顺序访问二维数组是一种常见的方式。这种方式通常更高效,因为内存布局通常是连续存储的。 ```cpp #include <iostream> using namespace std; void rowTraversal(int array[][4], int rows) { for (int i = 0; i < rows; ++i) { for (int j = 0; j < 4; ++j) { cout << array[i][j] << " "; } cout << endl; } } ``` 此代码展示了如何逐行打印二维数组的内容[^3]。 #### 3. 按列遍历二维数组 另一种遍历方式是按照列优先顺序访问二维数组。尽管这种方法可能不如按行遍历效率高,但在某些场景下仍然适用。 ```cpp void columnTraversal(int array[][4], int rows) { for (int j = 0; j < 4; ++j) { for (int i = 0; i < rows; ++i) { cout << array[i][j] << " "; } cout << endl; } } ``` 该函数实现了按列优先顺序输出二维数组中的元素。 #### 4. 查找特定元素及其索引 为了在一个二维数组查找某个特定值并返回其位置(即行列坐标),可以通过嵌套循环实现如下功能: ```cpp pair<int, int> findElement(const int array[][4], int rows, int target) { for (int i = 0; i < rows; ++i) { for (int j = 0; j < 4; ++j) { if (array[i][j] == target) { return make_pair(i, j); } } } return make_pair(-1, -1); // 如果未找到目标,则返回 (-1,-1) } ``` 上述代码片段提供了一种方法来定位给定数值的位置[^1]。 #### 性能差异分析 当处理大规模数据集时,不同方向上的迭代速度会受到缓存命中率的影响而有所区别。具体来说,由于现代计算机体系结构的特点——CPU高速缓存机制的存在,使得沿同一维度连续读取的数据能够更好地利用这些硬件特性从而提升性能表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值