zoukankan      html  css  js  c++  java
  • 二维数组中的查找(C++和Python实现)

    (说明:本博客中的题目题目详细说明参考代码均摘自 “何海涛《剑指Offer:名企面试官精讲典型编程题》2012年”)

    题目

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

      进一步的详细说明: 

      下图中的二维数组就是每行、每列都递增排序。如果在这个数组中查找数字 7,则返回 true;如果查找数字 5,由于数组不含有该数字,则返回 false。

           

    算法设计思想

      对于类似上图中的二维数组,选择从右上方(数字 9)或 左下方(数字 6)开始遍历,这样可以保证向单一方向缩小搜索范围;而从左上方(数字 1)或右下方(数字 15)开始遍历,可以朝两个方向进行进一步搜索,从而导致无法缩小范围。

    以查找数字 5 为例,
      若从左下方(数字 6)开始遍历,则由于数字 5 < 6 ,根据二维数组沿行从左到右递增,沿列从上到下递增,数字 5 可能位于数字 6 的上方或左侧,而数字 6 的左侧无元素,因此数字 5 只能位于数字 6 的上方,从而缩小了搜索范围;
      若从左上方(数字 1)开始遍历,则由于数字 5 > 1,根据二维数组沿行从左到右递增,沿列从上到下递增,数字 5 可能位于数字 1 的下方或右侧,而数字 1的下方和右侧均有元素,因此无法缩小搜索范围。

      以上说明,找到一个好的起点很重要,其会直接影响算法的可行性。

    C++ 实现

    #include <iostream>
    
    using namespace std;
    
    // Try to find 'target' from 'matrix' with 'rows' rows and 'cols' columns,
    // If found, return true; else return false
    bool Find(int* matrix, int rows, int cols, int target)
    {
        bool found = false;
    
        if (!matrix || rows < 0 || cols < 0)  // 易漏点
            return found;
        int i = 0;
        int j = cols-1;   // Note: the index of the last element in each row is cols-1. // 易错点
        while ((i < rows) && (j >= 0))
        {
            int current = *(matrix+i*cols+j);
    
            if (target < current)
                j--;
            else if (target > current)
                i++;
            else {  // target == current
                found = true;
                break;
            }
        }
    
        return found;
    }
    
    // Display the result whether the target is found.
    void display(int* matrix, int rows, int cols, int target)
    {
        cout << "Target " << target << " is ";
        if (Find(matrix, rows, cols, target))
            cout << "";
        else
            cout << "not ";
        cout << "found." << endl;
    }
    
    void unitest()
    {
        int mat[] = {1, 2,  8,  9,
                     2, 4,  9, 12,
                     4, 7, 10, 13,
                     6, 8, 11, 15};
        // Try to find digits 7 and 5, then display the result
        display(mat, 4, 4, 7);
        display(mat, 4, 4, 5);
    }
    
    int main()
    {
        unitest();
        return 0;
    }

    Python 实现

    #!/usr/bin/python
    # -*- coding: utf8 -*-
    
    
    # Try to find 'target' from 'matrix' with 'rows' rows and 'cols' columns,
    # If found, return true; else return false
    def find_target(matrix, rows, cols, target):
        found = False
        if not matrix or rows < 0 or cols < 0:  # 易漏点
            return found
        i, j = 0, cols-1  # 易错点
        while i < rows and j >= 0:
            current = matrix[i*cols+j]
            if target < current:
                j -= 1
            elif target > current:
                i += 1
            else:  # target == current
                found = True
                break
    
        return found
    
    
    def unitest():
        mat = [1, 2,  8,  9,
               2, 4,  9, 12,
               4, 7, 10, 13,
               6, 8, 11, 15]
        # Try to find digits 7 and 5, then display the result
        for target in [7, 5]:
            print "Target %d is %s found." % (target, "" if find_target(mat, 4, 4, target) else "not")
    
    if __name__ == "__main__":
        unitest()

    参考代码

    1. targetver.h

    #pragma once
    
    // The following macros define the minimum required platform.  The minimum required platform
    // is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run 
    // your application.  The macros work by enabling all features available on platform versions up to and 
    // including the version specified.
    
    // Modify the following defines if you have to target a platform prior to the ones specified below.
    // Refer to MSDN for the latest info on corresponding values for different platforms.
    #ifndef _WIN32_WINNT            // Specifies that the minimum required platform is Windows Vista.
    #define _WIN32_WINNT 0x0600     // Change this to the appropriate value to target other versions of Windows.
    #endif

    2. stdafx.h

    // stdafx.h : include file for standard system include files,
    // or project specific include files that are used frequently, but
    // are changed infrequently
    //
    
    #pragma once
    
    #include "targetver.h"
    
    #include <stdio.h>
    #include <tchar.h>
    
    
    
    // TODO: reference additional headers your program requires here

    3. stdafx.cpp

    // stdafx.cpp : source file that includes just the standard includes
    // FindInPartiallySortedMatrix.pch will be the pre-compiled header
    // stdafx.obj will contain the pre-compiled type information
    
    #include "stdafx.h"
    
    // TODO: reference any additional headers you need in STDAFX.H
    // and not in this file

    4. FindInPartiallySortedMatrix.cpp

    // FindInPartiallySortedMatrix.cpp : Defines the entry point for the console application.
    //
    
    // 《剑指Offer——名企面试官精讲典型编程题》代码
    // 著作权所有者:何海涛
    
    #include "stdafx.h"
    
    // 二维数组matrix中,每一行都从左到右递增排序,
    // 每一列都从上到下递增排序
    bool Find(int* matrix, int rows, int columns, int number)
    {
        bool found = false;
    
        if(matrix != NULL && rows > 0 && columns > 0)
        {
            int row = 0;
            int column = columns - 1;
            while(row < rows && column >=0)
            {
                if(matrix[row * columns + column] == number)
                {
                    found = true;
                    break;
                }
                else if(matrix[row * columns + column] > number)
                    -- column;
                else
                    ++ row;
            }
        }
    
        return found;
    }
    
    // ====================测试代码====================
    void Test(char* testName, int* matrix, int rows, int columns, int number, bool expected)
    {
        if(testName != NULL)
            printf("%s begins: ", testName);
    
        bool result = Find(matrix, rows, columns, number);
        if(result == expected)
            printf("Passed.
    ");
        else
            printf("Failed.
    ");
    }
    
    //  1   2   8   9
    //  2   4   9   12
    //  4   7   10  13
    //  6   8   11  15
    // 要查找的数在数组中
    void Test1()
    {
        int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
        Test("Test1", (int*)matrix, 4, 4, 7, true);
    }
    
    //  1   2   8   9
    //  2   4   9   12
    //  4   7   10  13
    //  6   8   11  15
    // 要查找的数不在数组中
    void Test2()
    {
        int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
        Test("Test2", (int*)matrix, 4, 4, 5, false);
    }
    
    //  1   2   8   9
    //  2   4   9   12
    //  4   7   10  13
    //  6   8   11  15
    // 要查找的数是数组中最小的数字
    void Test3()
    {
        int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
        Test("Test3", (int*)matrix, 4, 4, 1, true);
    }
    
    //  1   2   8   9
    //  2   4   9   12
    //  4   7   10  13
    //  6   8   11  15
    // 要查找的数是数组中最大的数字
    void Test4()
    {
        int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
        Test("Test4", (int*)matrix, 4, 4, 15, true);
    }
    
    //  1   2   8   9
    //  2   4   9   12
    //  4   7   10  13
    //  6   8   11  15
    // 要查找的数比数组中最小的数字还小
    void Test5()
    {
        int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
        Test("Test5", (int*)matrix, 4, 4, 0, false);
    }
    
    //  1   2   8   9
    //  2   4   9   12
    //  4   7   10  13
    //  6   8   11  15
    // 要查找的数比数组中最大的数字还大
    void Test6()
    {
        int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
        Test("Test6", (int*)matrix, 4, 4, 16, false);
    }
    
    // 鲁棒性测试,输入空指针
    void Test7()
    {
        Test("Test7", NULL, 0, 0, 16, false);
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        Test1();
        Test2();
        Test3();
        Test4();
        Test5();
        Test6();
        Test7();
    
        return 0;
    }

    5. 项目 03_FindInPartiallySortedMatrix 下载

    百度网盘: 03_FindInPartiallySortedMatrix.zip  

    参考资料

     [1]  何海涛. 剑指 Offer:名企面试官精讲典型编程题 [M]. 北京:电子工业出版社,2012. 38-41.

  • 相关阅读:
    Poj 2017 Speed Limit(水题)
    Poj 1316 Self Numbers(水题)
    Poj 1017 Packets(贪心策略)
    Poj 1017 Packets(贪心策略)
    Poj 2662,2909 Goldbach's Conjecture (素数判定)
    Poj 2662,2909 Goldbach's Conjecture (素数判定)
    poj 2388 Who's in the Middle(快速排序求中位数)
    poj 2388 Who's in the Middle(快速排序求中位数)
    poj 2000 Gold Coins(水题)
    poj 2000 Gold Coins(水题)
  • 原文地址:https://www.cnblogs.com/klchang/p/7470482.html
Copyright © 2011-2022 走看看