在给定的二维数组元素中查找对应值位置的两种方法

一、二维数组快速查找对应值

题目:给出已知的二维数组(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;
}

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值