一、二维数组快速查找对应值
题目:给出已知的二维数组(5*5)的所有元素值,要求编写函数求需要查询的值在该二维数组哪一行哪一列。
1.常规查询+技巧返回并确定其所在位置
#include<stdio.h>
int FindValue(int br[5][5], int row, int col, int val) {
int i, j;
for (i = 0; i < row; i++) {
if (val <= br[i][col - 1]) {
break;
}
}
if (i == row) return -1;//未找到其对应的行(val不在该二维数组内)
j = col - 1;
while (j >= 0 && val < br[i][j]) {
j--;
}
if (j == -1) return -1;//该对应行无对应的该元素
else if (val != br[i][j]) return -1;//该对应行无对应的该元素
else return i * row + j; //技巧
}
int main() {
const int n = 5;
const int m = 5;
int ar[n][m] = {
{1,3,5,7,9},
{10,12,14,16,18},
{20,22,24,26,28},
{30,32,34,36,38},
{40,42,44,46,48},
};
int val;
printf("请输入您要查询的值:\n");
scanf_s("%d", &val);
int pos = FindValue(ar, n, m, val);
if (pos != -1) {
printf("row:%d\n", pos / n);
printf("col:%d\n", pos % n);
}
else {
printf("您要查询的数字不在该二维数组内!\n");
}
return 0;
}
该题技巧在于函数返回值为i*row+j,考察二维数组在内存中行优先存储!这一组数下标从零开始,对应到第i行*row即该行前面所有元素个数+j就可以表示该元素在对应行的哪一位。
返回到主函数中时,用pos/n(取整)即是该元素所在行数(0~4),pos%n即为其在对应行哪一位(0~4)。
2.二分法查询(前提:这组数从小到大或从大到小有序排列!)
#include<stdio.h>
int FindValue(int br[5][5], int row, int col, int val) {
int* p = (int*)br;//数组名代表数组首元素地址
//二维数组内存中行优先存储,将其看作一个元素从小到大排列的一维数组
int n = row * col;//数组元素总个数
int left = 0, right = n - 1,mid;//数组下标从0开始
int pos = -1;
while (left <= right) {
mid= (left + right) / 2;
if (val < p[mid]) { //p[mid]+*(p+mid)
right = mid - 1;
}
else if (val > p[mid]) {
left = mid + 1;
}
else {
pos = mid;//val==p[mid],也包含了right==left时即为该数的情况
break;
}
}
return pos;
}
int main() {
const int n = 5;
const int m = 5;
int ar[n][m] = {
{1,3,5,7,9},
{10,12,14,16,18},
{20,22,24,26,28},
{30,32,34,36,38},
{40,42,44,46,48},
};
int val;
printf("请输入您要查询的值:\n");
scanf_s("%d", &val);
int pos = FindValue(ar, n, m, val);
if (pos != -1) {
printf("Row:%d\n", pos / n);
printf("Col:%d\n", pos % n);
}
else printf("该二维数组内无您要查询的值!\n");
return 0;
}