二分查找_模板学习(减治思想)

首先用一个题进行二分查找的引入

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素

示例 1:

输入: [1,3,5,6], 5
输出: 2
示例 2:

输入: [1,3,5,6], 2
输出: 1
示例 3:

输入: [1,3,5,6], 7
输出: 4
示例 4:

输入: [1,3,5,6], 0
输出: 0

分析

方法一:暴力解法

  • 从数组的左边遍历到右边,如果遇到相等的元素,直接返回下标;

  • 遇到第 1 个严格大于 target 的元素,返回这个元素的下标;

  • 如果数组里所有的元素都严格小于 target,返回数组的长度 len。

    public int searchInsert(int[] nums, int target) {
        for(int i = 0; i < nums.length; i++) {
            if(target <= nums[i]){
                return i;
            }
        }
        return nums.length;
    }

python

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        for i in range(len(nums)):
            if nums[i] >= target:
                return i

        return len(nums)
    
    
# 或者
class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
    if target in list:
        return list.index(target)
    else:
        list.append(target)
        list.sort()
        return list.index(target)

方法二: 二分查找

分析:在有序数组中查找插入元素的位置,显然可以使用二分查找。这篇题解提供的思路是「排除法」,思路是:在循环的过程中,不断排除不需要的解,最后剩下的那个元素的位置就一定是插入元素的位置。

具体来说:

  • 首先,插入位置有可能在数组的末尾(题目中的示例 3),需要单独判断,此时返回数组的长度;
  • 否则,根据示例和暴力解法的分析,插入的位置是大于等于 target第 1 个元素的位置。

因此,严格小于 target 的元素一定不是解,在循环体中将左右边界 leftright 逐渐向中间靠拢,最后 left 和 right 相遇,则找到了插入元素的位置。

插入元素的位置可能在数组的末尾下标的下一个(见例 3),因此在初始化右边界 right 的时候,可以设置成为数组的长度 len,根据这个思路,可以写出如下代码。

	public int searchInsert(int[] nums, int target) {
        int len = nums.length;
        if (len == 0) {
            return 0;
        }
        
        int left = 0;
        // 因为有可能数组的最后一个元素的位置的下一个是我们要找的,故右边界是 len
        int right = len;
        while (left < right) {
            int mid = left + (right - left) / 2;
            // 小于 target 的元素一定不是解
            if (nums[mid] < target) {
                // 下一轮搜索的区间是 [mid + 1, right]
                left = mid + 1;
            } else {
              	// 下一轮搜索的区间是 [left, mid]
                right = mid;
            }
        }
        return left;
    }
from typing import List


class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        size = len(nums)
        if size == 0:
            return 0

        left = 0
        # 因为有可能数组的最后一个元素的位置的下一个是我们要找的,故右边界是 len
        right = size
        while left < right:
            mid = (left + right) // 2
            # 严格小于 target 的元素一定不是解
            if nums[mid] < target:
                # 下一轮搜索区间是 [mid + 1, right]
                left = mid + 1
            else:
                right = mid
        return left

二分查找算法简介

在这里插入图片描述

二分查找的思想

减而治之,即将大规模问题转化成小规模问题。减而治之是分而治之的特例,将大问题划分成若干个子问题以后,最终答案只在其中一个子问题里。

生活中的二分查找

以前央视有一档节目叫《幸运 52》,里面有个游戏「猜价格」,主持人说猜高了,观众就往低了猜,主持人说猜低了,观众就往高了猜,直至猜中为止。

程序员定位 bug,经常是在一些逻辑关键点做一些变量的打印输出,以逐渐缩小查找范围,最终定位出问题的代码行(或者块)。

二分查找的基本问题(二分查找模板一)

「力扣」第 704 题:二分查找

思路:先看中间位置的元素,如果恰好等于,则直接返回中间位置的下标,否则看中间位置元素的值 nums[mid] 和 target 的关系决定下一轮在哪一侧寻找目标元素。

这个思路把待查找数组分为了 3 个部分:mid 所在位置,mid 的左边,mid 的右边。根据 mid 元素与目标元素的值的大小关系,如果 nums[mid] 恰好等于 target 直接返回就好了,否则根据不等关系,确定下一轮搜索的区间在哪里。

public class Solution {

    public int search(int[] nums, int target) {
        int len = nums.length;

        int left = 0;
        int right = len - 1;
        // 目标元素可能存在在区间 [left, right]
        while (left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] < target) {
                // 目标元素可能存在在区间 [mid + 1, right]
                left = mid + 1;
            } else {
                // 目标元素可能存在在区间 [left, mid - 1]
                right = mid - 1;
            }
        }
        return -1;
    }
}

说明:

  • 循环可以继续的条件是 while (left <= right) ,表示当 left == right 成立的时候,还有一个元素,即下标 left(right)位置的元素还没有看到,需要继续查看这个元素的值,看看是不是目标元素;

  • 关于取中间数 int mid = (left + right) / 2; 在 left + right 很大的时候会发生整形溢出,一般这样改写:

int mid = left + (right - left) / 2;

这两种写法事实上没有太大的区别,在 left 和 right 都表示数组下标的时候,几乎不会越界,因为绝大多数情况下不会开那么长的数组。

在 Java 中还可以这样写

int mid = (left + right) >>> 1;

>>>,它表示,在 left + right 发生整型溢出的时候,高位补 0,结果依然正确。这一点是从 JDK 的源码中 Arrays.binarySearch() 方法借鉴来的。

在 Python 中不用这样改写,Python 在 left + right 发生整型溢出的时候会自动转成长整形。

这里不建议把 / 2 改写成 >> 1,理由是高级语言在编译期间会做优化,会将 / 2,以及除以 2 的方幂的操作,在内部修改为 >>,工程师只需要写程序本来的逻辑就好了。如果使用位运算,在 C++ 中可能还需要注意运算优先级的问题。

为什么取二分之一?三分之一、五分之四可不可以?
(对于这道问题)当然可以,大家可以自行验证。结合二分查找的思路并不难理解,其实只要在数组中间任意找一个位置的元素,如果恰好是目标元素,则直接返回。如果不是根据这个元素的值和目标元素的大小关系,进而在当前位置的左侧还是右侧继续查找。

在我们对问题一无所知的时候,取中间数是最好的做法(如果有学习过《机器学习》熵的概念可能会有感触)。

还有一个细节,/ 2 表示的是下取整,当数组中的元素个数为偶数的时候,int mid = left + (right - left) / 2; 只能取到位于左边的那个元素。那么取位于右边的那个元素可以吗,当然可以,理由同上。
取右边中间数的表达式是(其实就是在括号里 + 1,表示上取整):

int mid = left + (right - left) / 2;
以上的代码可以认为是二分查找的模板一。下面我们介绍二分查找模板二,应用这个模板的思想可以解决「力扣」上很多二分查找算法的变种和一些复杂的二分查找问题。

二分查找模板二(在循环体里排除不存在目标元素的区间)

基本思想

从考虑哪些元素一定不是目标元素开始考虑。在本题解最开始其实已经介绍了:根据看到的 mid 位置的元素,排除掉一定不可能存在目标元素的区间,而下一轮在可能存在目标的子区间里继续查找。

具体做法

  • 先把循环可以继续的条件写成 while (left < right),表示退出循环的时候,[left, right] 这个区间里只有一个元素,这个元素有可能就是目标元素;
  • 写 if 和 else 语句的时候,思考当 nums[mid] 满足什么性质的时候,num[mid] 不是解,进而接着判断 mid 的左边有没有可能是解,mid 的右边有没有可能是解;
    说明:
  • 做题的经验告诉我,思考什么时候不是解比较好想。如果一个数要满足多个条件,只需要对其中一个条件取反,就可以达到缩小搜索范围的目的;
  • 此时 mid 作为待查找数组的分界,就把它分为两个区间:一个部分可能存在目标元素,一个部分一定不存在目标元素。

理解如何避免死循环(重难点)

根据 mid 被分到左边区间还是右边区间,代码写出来只有以下 2 种:

边界收缩行为 1: mid 被分到左边。即区间被分成 [left, mid][mid + 1, right],这里用「闭区间」表示区间端点可以取到,下同;

代码写出来是这样的:

if (check(mid)) {
    // 下一轮搜索区间是 [mid + 1, right],因此把左边界设置为 mid + 1 位置
    left = mid + 1;
} else {
    // 上面对了以后,剩下的区间一定是 [left, mid],因此右边界设置为 mid 位置
    right = mid;
}

说明:这里的 check(mid) 函数通常是一个表达式,在一些情况下有可能逻辑比较复杂,建议专门抽取成一个私有方法,以突显主干逻辑。

边界收缩行为 2: mid 被分到右边。即区间被分成 [left, mid - 1] 与 [mid, right];

同上,代码写出来是这样的:

if (check(mid)) {
    // 下一轮搜索区间是 [left, mid - 1],因此把右边界设置为 mid - 1 位置
    right = mid - 1;
} else {
    // 上面对了以后,剩下的区间一定是 [mid, right],因此左边界设置为 mid 位置
    left = mid;
}

面对面的边界收缩行为 2(mid 被分到右边),在待搜索区间收缩到只剩下 2 个元素的时候,就有可能造成死循环。搜索区间不能缩小,是造成死循环的原因

有了上面的分析,我们把上面「边界收缩行为」对应的中间数取法补上:

边界收缩行为 1: mid 被分到左边。即区间被分成 [left, mid] 与 [mid + 1, right],此时取中间数的时候下取整。

int mid = left + (right - left) / 2;
if (check(mid)) {
    // 下一轮搜索区间是 [mid + 1, right]
    left = mid + 1;
} else {
    right = mid;
}

边界收缩行为 2: mid 被分到右边。即区间被分成 **[left, mid - 1] 与 [mid, right],**此时取中间数的时候上取整。

int mid = left + (right - left + 1) / 2;
if (check(mid)) {
    // 下一轮搜索区间是 [left, mid - 1]
    right = mid - 1;
} else {
    left = mid;
}

如果这里有疑惑,大家在练习的过程中,当发生死循环的时候:在 while 循环里把 left、right、mid 变量的值打印出来看看,就很清楚了。

遇到几次死循环,调试正确以后,就能很清楚地记住下面这条规则:在 if else 语句里面只要出现 left = mid 的时候,把去中间数行为改成上取整即可。

二分查找模板二(在循环体里排除不存在目标元素的区间)的一般步骤

1、确定搜索区间初始化时候的左右边界,有时需要关注一下边界值。在初始化时,有时把搜索区间设置大一点没有关系,但是如果恰好把边界值排除在外,再怎么搜索都得不到结果;

例如本题(「力扣」第 35 题),如果一开始把 len 这个位置排除在外进行二分搜索(在之前也没有特判),代码是怎么都通不过评测系统的。

2、先写上 while (left < right) ,表示退出循环的条件是 left == right,对于返回左右边界就不用思考了,因此此时它们下标的值相等;

3、先写下取整的中间数取法,然后**从如何把 mid 排除掉的角度思考 if 和 else 语句应该怎样写。**这里建议写两个注释,非必需。

  • 一般而言,我都会把**「什么时候不是目标元素」作为注释写在代码中,提醒自己要判断正确,**这一步判断非常关键,直接影响到后面的代码逻辑;

  • 然后接着思考 mid 不是解的情况下,mid 的左右两边可能存在解,**把下一轮搜索的区间范围作为注释写进代码里,**进而在确定下一轮搜索区间边界的收缩行为时,不容易出错。

  • if 有把握写对的情况下,else 就是 if 的反面,可以不用思考,直接写出来。

说明:这种思考方式,就正正好把待搜索区间从逻辑上分成两个区间,一个区间不可能存在目标元素,进而在另一个区间里继续搜索,更符合二分的语义。

4、根据 if else 里面写的情况,看看是否需要修改中间数下取整的行为;

只有看到 left = mid 的时候,才需要调整成为上取整,记住这一点即可,我因为刚开始不理解这种写法,遇到很多次死循环,现在已经牢记在心了。

5、退出循环的时候,一定有 left == right 成立**。有些时候可以直接返回 left (或者 right,由于它们相等,后面都省略括弧)或者与 left 相关的数值,有些时候还须要再做一次判断,判断 left 与 right 是否是我们需要查找的元素,这一步叫「后处理」。**

本题就是这样,因为插入元素的位置,一定在搜索范围里,因此退出循环的时候,不用再做一次判断。

与其它二分查找模板的比较

while 里面的表达式决定了退出循环以后区间 [left, right] 有几个元素。几个模板的主要区别就在这里。

1、 while (left <= right) 事实上是把待搜索区间「三分」,if else 有三个分支,它直接面对目标元素,在目标元素在待搜索数组中有只有 1 个的时候,可能提前结束查找。但是如果目标元素没有在待搜索数组中存在,则不能节约搜索次数;

2、while (left < right) 是本题解推荐使用的思考方法,不建议背模板,建议的方法是多做题,掌握解题的思路和技巧;

优点是:更符合二分语义,不用去思考返回 left 还是 right,在退出循环的时候,有的时候,根据语境,不正确的数都排除掉,最后剩下的那个数就一定是目标值,不需要再做一次判断。

这种方法思考的细节最少,写程序不易出错。

缺点是:需要理解当分支逻辑出现 left = mid 的时候,要修改取中间数的行为,使其上取整。

3、while (left + 1 < right) 这种写法其实很多人都在用,如果你理解了本题解介绍的方法,理解它就很容易了。使用它在退出循环的时候,有 left + 1 = right 成立,即 left 和 right夹成的区间里一定有 2 个元素,此时需要分别判断 left 和 right 位置的元素是不是目标元素,有时需要注意判断的先后顺序。

优点:不用去理解和处理第 2 点说的那种上取整的行为,因为不会出现死循环。
缺点:

  • while (left + 1 < right) 这种写法我个人认为不那么自然;
  • 一定需要后处理,在后处理这个问题上增加了思考的负担;
  • left = midright = mid 这种写法比较随意,而事实上,程序员完全有能力决定 mid 是保留还是被排除在外。

补充:二分查找变体(来自极客APP专栏)

// 查找第一个值等于给定值的元素
private int firstEquals(int[] arr, int target) {
    int l = 0, r = arr.length - 1;
    while (l < r) {
        int mid = l + ((r - l) >> 1);
        if (arr[mid] < target) l = mid + 1;
        else r = mid; // 收缩右边界不影响 first equals
    }
    if (arr[l] == target && (l == 0 || arr[l - 1] < target)) return l;
    return -1;
}
// 查找最后一个值等于给定值的元素
private int lastEquals(int[] arr, int target) {
    int l = 0, r = arr.length - 1;
    while (l < r) {
        int mid = l + ((r - l + 1) >> 1);
        if (arr[mid] > target) r = mid - 1;
        else l = mid; // 收缩左边界不影响 last equals
    }
    if (arr[l] == target && (l == arr.length - 1 || arr[l + 1] > target)) return l;
    return -1;
}
// 查找第一个大于等于给定值的元素
private int firstLargeOrEquals(int[] arr, int target) {
    int l = 0, r = arr.length - 1;
    while (l < r) {
        int mid = l + ((r - l) >> 1);
        if (arr[mid] < target) l = mid + 1;
        else r = mid; // 收缩右边界不影响 first equals
    }
    if (arr[l] >= target && (l == 0 || arr[l - 1] < target)) return l; // >=
    return -1;
}
// 查找最后一个小于等于给定值的元素
private int lastLessOrEquals(int[] arr, int target) {
    int l = 0, r = arr.length - 1;
    while (l < r) {
        int mid = l + ((r - l + 1) >> 1);
        if (arr[mid] > target) r = mid - 1;
        else l = mid; // 收缩左边界不影响 last equals
    }
    if (arr[l] <= target && (l == arr.length - 1 || arr[l + 1] > target)) return l; // <=
    return -1;
}

注:本博为自身二分查找学习的记录收藏,以上二分查找的内容均截取自liweiwei1419,威威哥写的真的挺棒,为大家推荐一波

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
计算机算法与程序设计(python)_计算机 演讲人 202x-11-11 202x 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第1页。 第一章绪论(4学时) 01 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第2页。 第一章绪论(4学时) 1.1课程简介 01 1.2raptor流程图 02 1.3python简介及编程 03 1.42019年-学生的特色作品1 04 1.42019年-学生的特色作品2 05 1.52020年-学生特色作品-爬虫,机器学习与神经网络 06 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第3页。 第一章绪论(4学时) 1.52020年-学生特色作品-游戏 1.52020年-学生特色作品-其他 第一章测验 第一章编程作业 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第4页。 第二章穷举搜索问题(2学时) 02 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第5页。 第二章穷举搜索问题(2学时) M.94275.CN 2.2穷举搜索 02 第二章测验 05 2.1故事:案件回顾 01 2.4穷举搜索操作与编程实现 04 2.3故事:寻找billy 03 第二章编程作业 06 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第6页。 第三章字符串与数组(2学时) 03 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第7页。 3.1数组 3.2字符串 第三章测验 第三章编程作业 第三章字符串与数组(2学时) 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第8页。 第四章二分搜索与递归(4学时) 04 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第9页。 4.1二分搜索 4.2递归 4.3圆二分搜索 第四章测验 第四章编程作业(更正) 第四章二分搜索与递归(4学时) 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第10页。 第五章广度优先搜索与队列 05 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第11页。 第五章广度优先搜索与队列 5.1广度优先搜索 5.2队列与广度优先搜索求最短路径的实现 第五章测试 第五章编程作业 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第12页。 第六章深度优先搜索与栈 06 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第13页。 第六章深度优先搜索与栈 6.1深度优先搜索与栈 6.2栈与队列 第六章测验 第六章编程作业 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第14页。 第七章并行算法,迭代加深与逆向索引 07 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第15页。 7.1并行算法 01 06 第七章测验 03 7.4作业提示 7.3逆向索引 第七章编程作业 02 7.2迭代加深 04 05 第七章并行算法,迭代加深与逆向索引 单击此处添加文本具体内容,简明扼要的阐述您的观点。根据需要可酌情增减文字,以便观者准确的理解您传达的思想。 单击此处添加标题 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第16页。 第八章二叉搜索树 08 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第17页。 第八章二叉搜索树 01 8.1二叉搜索树的定义与查找 02 8.2二叉搜索树的实现 03 8.3有序数组构造二叉搜索树 04 8.4二叉搜索树的区间查找 05 8.5二叉搜索树的插入 06 8.6trie树 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第18页。 第八章二叉搜索树 第八章测验 第八章编程作业 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第19页。 第九章最佳搜索与堆 09 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第20页。 第九章最佳搜索与堆 M.94275.CN 9.1最佳搜索 9.2优先队列 9.3堆 第九章测验 9.5总结 9.4大结局 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第21页。 第九章最佳搜索与堆 第九章编程作业 计算机算法与程序设计(python)-计算机PPT模板全文共34页,当前为第22页。 第二部分高级应用1 10 计算机算法与程序
VC++ MFC 经典教程 - 基础篇 1.CP_YourFirstWindowsProgram.mp4 10.MFC_GDI_画直线和曲线.mp4 11.MFC_GDI_画椭圆_多边形及其他形状.mp4 12.MFC_GDI_画笔和画刷.mp4 13.MFC_GDI_画文本和字体.mp4 14.MFC_GDI_备用对象和取消选定.mp4 15.MFC_Ruler.mp4 16.MFC_窗口滚动条.mp4 17.MFC_Accel.mp4 18.MFC_Accel(2).mp4 19.MFC_消息框.mp4 2.Windows_编程模型.mp4 20MFC_客户区鼠标消息.mp4 21.MFC_TicTac-1.mp4 22.MFC_TicTac-2.mp4 23.MFC_TicTac-3.mp4 24.MFC_鼠标滚轮.mp4 25.MFC_捕获鼠标.mp4 26.MFC_VisualKB-1.mp4 27.MFC_VisualKB-2.mp4 29.MFC_菜单.mp4 3.MFC_第一个MFC程序设计.mp4 30.MFC_CButton类.mp4 31.MFC_E_FontView-1.mp4 32.MFC_E_FontView-2.mp4 33.MFC_CEdit类.mp4 34.MFC_MyPad.mp4 35.MFC_对话框_静态文本_编辑框.mp4 36.MFC_对话框_访问控件_7种方法_A.mp4 37.MFC_对话框_访问控件_7种方法_B.mp4 38.MFC_对话框_访问控件_7种方法_C.mp4 39.MFC_对话框_复选框_单选钮.mp4 4.MFC_消息映射.mp4 40.MFC_模态对话框.mp4 41.MFC_非模态对话框.mp4 42.MFC_属性表.mp4 43.MFC_公用对话框.mp4 44.MFC_数组类-1.mp4 45.MFC_数组类-2.mp4 46.MFC_CArray.mp4 47.MFC_列表类.mp4 48.MFC_映射类.mp4 49.MFC_类型指针类.mp4 5.MFC_使用向导快速进行MFC程序设计.mp4 50.MFC_CFile.mp4 51.MFC_CArchive.mp4 52.MFC_四个对象四种方法.mp4 53. MFC_Ruler.mp4 54.MFC_Ruler.mp4 55.MFC_Ruler.mp4 56.MFC_SdiSquares.mp4 57.MFC_Scroll_Ruler.mp4 58.MFC_CHtmlView.mp4 59.MFC_CTreeView.mp4 6.MFC_字符集和TEXT宏.mp4 60.MFC_CListView.mp4 61.MFC_MdiSquares.mp4 62.MFC_动态拆分窗口.mp4 63.MFC_ToolBar.mp4 64.MFC_ToolBar_Ex13a.mp4 65.MFC_StatusBar.mp4 66.MFC_StatusBar_Ex13b.mp4 67.MFC_Rebar.mp4 68.MFC_EZPrint.mp4 69.MFC_Print_Bubble.mp4 7.MFC_建立应用程序.mp4 8.MFC_第一个MFC程序设计(不用向导).mp4 9.MFC_Windows_GDI_设备描述表类.mp4 数据结构算法_C语言 01.swap.mp4 02.BubbleSort.mp4 03.SelecttionSort.mp4 04.顺序查找.mp4 05.C_DS_折半查找.mp4 06.递归.mp4 07递归算法_折半查找.mp4 08.Permutations.mp4 09.插入排序.mp4 10.快速排序.mp4 11.归并排序.mp4 12.顺序栈.mp4 13.顺序队列.mp4 14.链表的基本概念.mp4 15.单链表的基本运算.mp4 16.循环单链表.mp4 17.双向链表.mp4 18.链式栈.mp4 19.链式队列.mp4 20.基数排序.mp4 21.树.mp4 22.二叉树的存储表示与实现.mp4 23.二叉树的遍历.mp4 24.二叉查找树.mp4 25.红黑树.mp4 26.堆.mp4 27.堆排序.mp4 28.哈希表.mp4 29.图_邻接矩阵
操作系统要求 具备跨平台特性,支持 Linux/Unix及Windows 2000/2003/XP/7/2008/等操作系统。 针对上述操作系统,我们对软件做了大量的测试和实地检验,保证可以安全稳定的运行,但您仍需做好服务器操作系统的安全防备措施,例如Windows用户需更改MYSQL的初始密码,使用较新的稳定的软件版本等。 语言及数据库支撑环境要求 * 可用的 web 服务器(如 Apache、Zeus、IIS 等) * PHP5.x及以上 * MySQL5.x及以上 如果您租用虚拟主机,请咨询虚拟主机提供商,您的空间服务器是否已安装了上述软件。 由于 的数据表具有前缀设计,因此通常情况下可以将与其他软件安装在同一个数据库中,或采用不同的前缀名在同一个数据库中安装多个系统而不产生冲突。 您的 MySQL 数据库账号应当拥有 CREATE、DROP、ALTER 等执行权限。 一、安装步骤: 1、下载提供的zip压缩包 解压 /upload 文件夹内容到网站目录下 2、第一次访问人才系统,会自动提示安装数据库到你的mysql中 3、安装完成后再次访问即可正常浏览系统或后台 4、安装文件在 /install 目录下,【注意】安装完成后请删除或者修改此文件夹保证安全【注意】 5、为了后台安全大家可以任意修改 admin 文件夹名称 如 admin_123 二、PHP云人才系统产品特点: (1)、PHP OOP思想编写方便维护和升级有很好的安全性 (2)、采用PHP模板分离可以方便修改页面和二次开发升级 (3)、企业会员和个人会员分别使用独立的管理的权限模式不产生冲突方便管理 三、PHP云人才系统产品常见功能: (1)、个人会员拥有单账户多简历,快速根据不同企业投放不同简历 (2)、个人会员可以通过创建标准简历和黏贴简历模式快速建立自己的简历信息 (3)、个人会员可以通过搜索、收藏、投放等功能来管理个人求职情况 (4)、个人会员可以通过申请、推荐模式找到精确的企业 (5)、企业会员可以分为、普通会员、季度会员、年会员三类收费和管理 (6)、企业会员可以发布不同简历和悬赏简历从而推荐到优先的位置 (7)、企业会员可以通过申请广告运营者可以从中获得收入 (8)、总后台可以通过审核、配置、预览,查找配合网站运营操作猎头服务 四、PHP云人才系统特色功能: (1)、PC客户端 (2)、微信客户端 (3)、微信红包功能 (4)、微信支付功能 (5)、猎头 (6)、手机APP (7)、问答、朋友圈 (8)、站内、外数据调用 (9)、分站独立关键字、LOGO、自定义首页等 (10)、地图搜索等 PHP云 4.2 更新日志 一、新增功能: 1.新增:注册送优惠卷功能 2.新增:优惠卷用户互转功能 3.新增:简历外发功能 4.新增:WAP后台管理系统 5.新增:WAP积分商城 6.新增:后台数据统计功能 7.新增:职位分类描述功能 8.新增:分类支持(多分类)录入功能 9.新增:后台推广营销功能 10.新增:WAP首页广告位功能 11.新增:简历同步功能(求职者可以把第三方网站简历,同步到本网站中。) 12.新增:找回密码“帐号申诉”功能 13.新增:支持PC与WAP网址互换功能 14.新增:培训课程订购功能 15.新增:店铺招聘,后台增加联系方式登录开关功能 16.新增:WAP手机号码模式注册功能 17.新增:新闻分类转移功能 18.新增:新闻支持关联关健词连接功能 19.新增:企业职位管理:批量自动刷新、批量删除职位和一键暂停招聘功能 20.新增:职位匹配简历功能 21.新增:简历模板功能 22.新增:微信模板消息功能 23.新增:个人用户黑名单功能 24.新增:后台-欢迎页新增:“网站动态和会员日志”功能 25.新增:后台(会员注册开关) 26.新增:普工联系方式开关 27.新增:查看企业联系信息开关 28.新增:登录才能搜索简历功能 29.新增:培训用户支持邮件功能 30.新增:广告位支持联盟广告代码功能 31.新增:wap版微信支付 32.新增:wap微信登录 33.新增:UC支持UTF-8整合 34.新增:wap问答模块 二、修复 1.修复:WAP、PC版针对IE、火狐、谷歌浏览版本兼容性问题 2.修复:猎头注册默认等级问题 3.修复:短信问题 4.修复:企业地图问题 5.修复:积分商城产品、完善地址问题 6.修复:WAP分享功能问题 7.修复:WAP快捷登陆问题 8.修复:WAP个人、企业会员问题 9.修复:下载简历BUG问题 10.修复:培训会员问题 11.修复:猎头会员发布职位

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值