【练习题】二分法

传统二分

特点:

在一个有序、无重复元素的数组中找出某个关键字

二分查找步骤:

  • 循环的条件是:left <= right

1、用三个指针leftmidright分别指向数组头、中间、尾leftright之间是待查找区

2、在待查找区间中,如果数组中间位置mid指向的值等于目标值,则表示已找到目标值

3、 否则:

​ ①. 如果数组中间位置mid指向的值小于目标值,则更新待查找区的最左端为中间位置mid的后一个位置:left = mid + 1

​ ②. 如果数组中间位置mid指向的值大于目标值,则更新待查找区的最右端为中间位置mid的前一个位置:right = mid - 1

【注意】:rightleft指向相同的值时:如果目标值等于该值,则找到,否则,表示该数组中没有目标值。

4、 反复进行,直到查找成果或范围缩小为空(left > right)即查找不成功为止

代码演示:

int binary_search(int target, int *num, int len) {
    int left = 0, right = len - 1;
    while (left <= right) {
    	int mid = (left + right) / 2;
    	if (target == num[mid]) return mid;
    	else if (target > num[mid]) left = mid + 1;
    	else right = mid - 1;
    }
    //找不到,返回-1
    return -1;
}

01问题之找出第一个1的位置

问题:

一串字符串,前部分由小写组成,后部分由大写组成,找出字符串中第一个大写字母。

思路:

将所有大写字母全用1来表示,小写字母用0表示

步骤:

  • 循环的条件是:left < right
  1. 写一个函数,用来把单个字符变为01

  2. 用三个指针leftmidright分别指向数组头、中间、尾。

  3. 如果数组中间位置mid指向的字符等于1(即该字符是大写),则让尾部right更新到mid所站的位置:right = mid

    (因为right更新到的mid位置有可能是第一个1出现的位置)

  4. 否则如果数组中间位置mid指向的字符不是1,让left更新到mid的后一个位置:left = mid + 1

    (因为已经确定mid指向的是小写)

  5. (left == right)时,就表示找到了第一个大写字母,否则找不到第一个大写字母

代码演示:

int is_A(char str) {
    if (str >= 'A' && str <= 'Z') {
        return 1;
    }
    return 0;
}
int find_first_capital_letter(char *str, int len) {
    int left = 0, right = len - 1, mid;
    while (left < right) {
        mid = (right + left ) / 2;
        if (is_A(str[mid]) == 1) right = mid;
        else left = mid + 1;
    }
    if (right == left) return left;
    return -1;
}
01问题之找出最后一个0的位置

步骤:

  1. 头(left),尾(right),中间(mid)三个指针
  2. 如果mid0left调到mid的位置:left = mid;
  3. 如果mid1right调到mid的前一个位置:right = mid - 1;

(详细步骤参看01问题之找出第一个1的位置)

二分法进行数值运算——求解方程

题目:

给你一个方程:x^4 + 5 * x^3 + 6 * x^2 + 7 * x + 4 = y,接受一个参数y,求出y值对应的、在0到100的范围内的解x,并返回,若范围内没有,则返回-1.

思路:

无穷趋近于一个值,我们就说这个值是他的解

【注意】y < 4y > x^4 + 5 * x^3 + 6 * x^2 + 7 * x + 4时(即等式不成立时),直接返回-1 (无解)

步骤:

  1. 设三个指针分别指向头,中,尾,其中,头=区间头,尾=区间尾
  2. 如果等式左边结果小于等于y,则left更新为mid所在的位置
  3. 如果等式左边结果大于y,则right更新为mid所在的的位置

代码演示:

#include <math.h>
#define ESP 1e-6
double solve_equation(double y) {
    if (4 > y || y > pow(100, 4) + 5 * pow(100, 3) + 6 * 100 * 100 + 7 * 100 + 4) return -1;
    double left = 0, right = 100, mid;
    while (right - left > ESP) {
        mid = (left + right) / 2;
        if (pow(mid, 4) + 5 * pow(mid, 3) + 6 * mid * mid + 7 * mid + 4 <= y) left = mid;
        else right = mid;
    }
	return left;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在给定的代码,并没有使用到二分法来查找字符串的比较结果。代码使用了strcmp函数来比较两个字符串的大小。strcmp函数返回一个整数值,表示两个字符串的大小关系。如果返回值为0,则表示两个字符串相等;如果返回值小于0,则表示第一个字符串小于第二个字符串;如果返回值大于0,则表示第一个字符串大于第二个字符串。在代码的while循环使用了strcmp函数来比较buff[mid].num和search两个字符串的大小。根据比较结果,通过调整base和top的值来缩小查找范围。如果strcmp的返回值为0,则说明找到了目标字符串,将其索引赋给ans;如果strcmp的返回值大于0,则说明目标字符串在左半部分,将top的值调整为mid-1;如果strcmp的返回值小于0,则说明目标字符串在右半部分,将base的值调整为mid+1。最终,通过判断ans的值来确定是否找到了目标字符串。<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [二分法查找学生信息](https://blog.csdn.net/okkil/article/details/104248307)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [c程序设计习题参考(谭浩强三版)习题参考解答](https://download.csdn.net/download/wmxnzn/2656246)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值