(五)王道机试指南___查找

算例1

  • 题目描述

  • 解题思路

①常规的题目,只需要用数组即可解决

  • 解题代码

#include <stdio.h>
int main() {
	int buf[200];
	int n;
	while (scanf("%d", &n) != EOF) {
		for (int i = 0; i < n;i++) {
			scanf("%d", &buf[i]);
		} //输入数据
		int x, ans = -1; //初始化答案为-1,以期在找不到答案时能正确的输出-1
		scanf("%d", &x);
		for (int i = 0; i < n;i++) { //依次遍历数组元素
			if (x == buf[i]) { // 目标数字与数组元素依次比较
				ans = i;
				break; //找到答案后跳出循环
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}
  • 注意点

①在满足时空要求的前提下,用线性遍历即可

算例2

  • 题目描述

  • 解题思路

①线性查找的时间复杂度在O(L),而二分查找的时间复杂度在O(logL)

②1000 x 10000 千万级已经超过了规定的时间复杂度,故不可以使用遍历查找

  • 解题代吗

#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
struct Student { //用于表示学生个体的结构体
	char no[100]; //学号
	char name[100]; //姓名
	int age; //年龄
	char sex[5]; //性别
	bool operator < (const Student & A) const { //重载小于运算符使其能使用sort函数排序
			return strcmp(no, A.no) < 0;
	}
}buf[1000];
int main() {
	int n;
	while (scanf("%d", &n) != EOF) {
		for (int i = 0; i < n;i++) {
			scanf("%s%s%s%d",
				buf[i].no, buf[i].name, buf[i].sex, &buf[i].age);
		} //输入
		sort(buf, buf + n); //对数组排序使其按照学号升序排列
		int t;
		scanf("%d", &t); //有t组询问
		while (t-- != 0) { //while 循环保证查询次数为t
			int ans = -1; //目标元素下标,初始化为-1
			char x[30];
			scanf("%s", x); //待查找学号
			int top = n - 1, base = 0; //初试时,开始下标0,结束下标n-1,查找子集为整个数组
				while (top >= base) { //当查找子集不为空集时重复二分查找
					int mid = (top + base) / 2; //计算中间点下标
					int tmp = strcmp(buf[mid].no, x); //比较中间点学号与目标学号
					if (tmp == 0) {
						ans = mid;
						break; //若相等,则查找完成跳出二分查找
					}
					else if (tmp > 0) top = mid - 1; // 若大于,则结束下标变为中间点前一个点下标
					else base = mid + 1; //若小于,则开始点下标变为中间点后一个点坐标
				}
			if (ans == -1) { //若查找失败
				printf("No Answer!\n");
			}
			else printf("%s %s %s %d\n",
				buf[ans].no, buf[ans].name, buf[ans].sex, buf[ans].age); //若查找成功
		}
	}
	return 0;
}
  • 注意点

①运用二分查找之后,时间复杂度被优化到O(nlogn+m*logn)

②也可以使用cmp函数进行排序(重载是个好东西)

bool cmp(Stu a, Stu b) {
	return a.id < b.id;
}
//····
sort(buf,buf+n,cmp);

③二分法查找还有一个非常重要的功能:定界。试思考下面问题:

算法思路:

// 存在一个升序有序的数组buf,其大小为size,目标数字为target
int base = 0, top = size; //初始情况与二分查找一致
while (base <= top) { //二分循环条件与二分查找一致
	int mid = (base + top) / 2;
	if (buf[mid] <= target) base = mid + 1; //符合前一部分数字规定
	else top = mid - 1; //否则
}
int ans = top; //最后,top即为我们要求的数字数组下标,buf[top] 为该数字本身

猜你喜欢

转载自blog.csdn.net/weixin_40614231/article/details/84072889