1 // 二维数组的查找.cpp : 定义控制台应用程序的入口点。
2 //
3 /****************************************************
4
5 代码设计者:cslave
6 代码声明:本代码可以用于商用,拷贝,或复制均可,但是
7 由使用本代码不当所导致的问题,本人概不负责。
8 设计时间:2012.6.25
9 题目说明:在一个二维数组中,每一行都按照从左到右递增的顺序排序
10 每一列都按照从上到下递增的顺序排序,请完成一个函数,输入这样的
11 一个二维数组和一个整数,判断数组中是否含有该整数。
12 例如下列的二维数组,每行每列都是递增排序,如果在这个数组中查找
13 数字7,则返回 true,如果查找数字5,由于数组中不存在该数字,则
14 返回false。
15
16 1 2 8 9
17 2 4 9 12
18 4 7 10 13
19 6 8 11 15
20
21
22 ****************************************************/
23
24
25 #include "stdafx.h"
26 #include <stdio.h>
27 #include <stdlib.h>
28
29 #define Rlimit 4
30 #define Climit 4
31
32 int arr[4][4]={{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}};
33
34 int LinearArr[16]={1,2,8,9,2,4,9,12,4,7,10,13,6,8,11,15};
35 /***********以下为杨氏矩阵的二维数组格式递归查找*************/
36 template<typename ElemType>
37 bool FindRecur(ElemType** Arr,int Row,int Column,ElemType Number)
38 {
39 if(Arr==NULL||Row>=Rlimit||Column>=Climit)
40 return false;
41 if(Arr!=NULL&&Row>=0&&Column>=0)
42 {
43 if(Number==Arr[Row][Column])
44 return true;
45 else if(Number<Arr[Row][Column])
46 {
47 return FindRecur(Arr,Row,Column-1,Number);
48 }
49 else
50 {
51 return FindRecur(Arr,Row+1,Column,Number);
52 }
53 }
54 return false;
55 }
56
57 /***********以下为杨氏矩阵的二维数组格式迭代查找*************/
58 template<typename ElemType>
59 bool FindIter(ElemType** Arr,int Row,int Column,ElemType Number)
60 {
61 bool Found=false;
62 if(Arr==NULL||Row>=Rlimit||Column>=Climit)
63 return false;
64 while(Arr!=NULL&&Row<Rlimit&&Column>=0)
65 {
66 if(Number==Arr[Row][Column])
67 {
68 Found=true;
69 break;
70 }
71 else if(Number<Arr[Row][Column])
72 {
73 Column--;
74 }
75 else
76 {
77 Row++;
78 }
79 }
80 return Found;
81
82 }
83
84 /***********以下为杨氏矩阵的一维数组格式迭代查找*************/
85 template<typename ElemType>
86 bool FindLinear(ElemType* Arr,int Rows,int Columns,ElemType Number)
87 {
88 bool Found=false;
89 if(Arr!=NULL&&Rows>=0&&Columns>=0)
90 {
91 int row=0;
92 int column=Columns-1;
93 while(row<Rows&&column>=0)
94 {
95 if(Arr[row*Columns+column]==Number)
96 {
97 Found=true;
98 break;
99 }
100 else if(Arr[row*Columns+column]>Number)
101 --column;
102 else
103 ++row;
104 }
105 }
106 return Found;
107
108 }
109 int _tmain(int argc, _TCHAR* argv[])
110 {
111 int *p[4];
112 p[0]=arr[0];
113 p[1]=arr[1];
114 p[2]=arr[2];
115 p[3]=arr[3];
116 if(FindRecur<int>(p,0,3,7))
117 printf("FindRecur Find it");
118 if(FindIter<int>(p,0,3,7))
119 printf("FindIter Find it");
120 if(FindLinear<int>(LinearArr,4,4,7))
121 printf("FindLinear Find it");
122 return 0;
123 }
124
125
126
127 /************************************************************************
128 ****************************我是分割线***********************************
129 编程后话:
130 关于二维数据作为函数参数传值问题:
131 将二维数组名等同于二级指针是错误的。
132 二维数组还是线性存储,只是这个线性存储又被划分为了长度相同的若干段,
133 二维数组名本质上应是指向这个线性存储的头指针。
134 所以直接将二维数组名当做二级指针传递显然是错误的。
135
136 二维数组作为函数参数传值由三种方法:
137 方法一:
138 形参给出第二维的长度。
139 这种方案不好,原因很简单,给出第二维长度影响代码的可移植性。
140 方法二:
141 形参声明为指向数组的指针。
142 这种方案实际上是上述方案的翻版,下面会介绍。
143 方法三:
144 形参声明为指针的指针,即为二级指针,这种方案较好。
145 *************************我是分割线*************************************
146 ************************************************************************/
147
148 /********************** 方法一: 形参给出第二维的长度*********************/
149 #include <stdio.h>
150 void func(int n, char str[][5])
151 {
152 int i;
153 for (i = 0; i < n; i++)
154 {
155 printf("\nstr[%d] = %s\n", i, str[i]);
156 }
157 }
158 void main()
159 {
160 char str[][5] = {"abc", "def", "ghi"};
161 func(3, str);
162 }
163
164 /********************** 方法二: 形参声明为指向数组的指针*******************/
165 #include <stdio.h>
166 void func(int n, char ( *str)[5])
167 {
168 int i;
169 for (i = 0; i < n; i++)
170 {
171 printf("\nstr[%d] = %s\n", i, str[i]);
172 }
173 }
174 void main()
175 {
176 char str[][5] = {"abc", "def", "ghi"};
177 func(3, str);
178 }
179
180 /********************** 方法三:形参声明为指针的指针*******************/
181
182 #include <stdio.h>
183 void func(int n, char **str)
184 {
185 int i;
186 for (i = 0; i < n; i++)
187 {
188 printf("\nstr[%d] = %s\n", i, str[i]);
189 }
190 }
191 void main()
192 {
193 char *p[3];
194 char str[][5] = {"abc", "def", "ghi"};
195 p[0] = str[0];
196 p[1] = str[1];
197 p[2] = str[2];
198 func(3, p); //这里要注意传值的必须是二级指针,再次重复一遍,二维数组名不是二维指针。
199 }
200
201 //当然你还可以这样进行使用
202 #include <string>
203 #include <iostream>
204 using namespace std;
205
206 int returnturn(char**name,char givers[],int NP)
207 {
208 int i;
209 for(i=0;i<NP;i++)
210 {
211 if(!strcmp(name[i],givers))
212 return i;
213 }
214 return -1;
215 }
216
217 int _tmain(int argc, _TCHAR* argv[])
218 {
219 int NP=3;
220 char**name=new char*[NP];
221 for(int k=0;k<NP;k++)
222 name[k]=new char[15];
223 for(int k=0;k<NP;k++)
224 cin>>name[k];
225 char begiver[]="hello";
226 cout<<returnturn(name,begiver,NP);//传给name的依然是二维指针name
227 return 0;
228 }