📜  N-Base 改进的二分搜索算法

📅  最后修改于: 2022-05-13 01:56:06.305000             🧑  作者: Mango

N-Base 改进的二分搜索算法

N-Base modified Binary Search是一种基于数基的算法,可用于在排序数组 arr[] 中查找元素。该算法是按位二分查找的扩展,运行时间相似。

例子:

直觉:一个数系的所有数字都可以用另一个数系来表示,该数系以任何数(例如2、3、7)为基础。例如,十进制数字系统的 7在以 3为底的数字系统中可以表示为(21 ) 3 。因此,可以使用任何数N作为数系的基数来实现按位二进制搜索的概念。

方法:通过将基数(从 2 开始的任何正整数)的幂加到总和(最初为 0)来搜索目标元素的索引。当找到这样的幂时,计算可以用于找到目标索引的次数,并将该值与总和相加。计算一个幂可以使用多少次的部分类似于二分查找文章中的“按位二分查找”。

  1. 定义一个基数,以及大于或等于基数的 2 的幂(2 的幂将有助于计算可以有效地将基数添加到最终索引的次数)
  2. 计算大于数组大小的基数 (N)的第一次幂。 ( N k其中 k 是大于或等于 1 的整数,X k是大于或等于数组大小的基数的第一次幂)。
  3. 将索引(finId)初始化为 0,它将存储目标元素应该在所有迭代结束时的最终位置
  4. 在计算的功率大于 0 时循环,并且每次将其除以基值。
    1. 检查此电源可以使用多少次并将该值添加到 finId。
    2. 要检查这一点,请使用下面提到的条件:

迭代完成时检查最终索引处的值是否与目标相同。如果不是,则该值不存在于数组中。

插图:请参阅下图以更好地理解。

笔记:

  1. 在每次迭代中,可以使用最大(Base – 1)次功率
  2. 基数可以是从 2 开始的任何正整数
  3. 需要对数组进行排序以执行此搜索算法

下面是上述方法的实现(与经典的二分搜索算法相比):

C++
// C++ code to implement the above approach
#include
using namespace std;
  
#define N 3
#define PowerOf2 4
  
int Numeric_Base_Search(int arr[], int M, 
                        int target){
    unsigned long long i, step1, 
    step2 = PowerOf2, times;
  
    // Find the first power of N 
    // greater than the array size
    for (step1 = 1; step1 < M; step1 *= N);
      
    for (i = 0; step1; step1 /= N)
  
        // Each time a power can be used
        // count how many times 
        // it can be used
        if (i + step1 < M && arr[i + step1] 
            <= target){
            for (times = 1; step2; 
                 step2 >>= 1)
                if (i + 
                    (step1 * (times + step2)) 
                    < M && 
                    arr[i + 
                      (step1 * (times + step2))] 
                    <= target)
                    times += step2;
  
            step2 = PowerOf2;
  
            // Add to final result 
            // how many times 
            // can the power be used
            i += times * step1;
        }
  
    // Return the index 
    // if the element is present in array
    // else return -1
    return arr[i] == target ? i : -1;
}
  
// Driver code
int main(){
    int arr[10] = 
    {1, 4, 5, 8, 11, 15, 21, 45, 70, 100};
    int target = 45, M = 10;
    int answer  = Numeric_Base_Search(arr, M, target);
    cout<


Java
// Java code to implement the above approach
class GFG {
  
    static int N = 3;
    static int PowerOf2 = 4;
  
    static int Numeric_Base_Search(int[] arr, int M,
                                   int target)
    {
        int i, step1, step2 = PowerOf2, times;
  
        // Find the first power of N
        // greater than the array size
        for (step1 = 1; step1 < M; step1 *= N)
            ;
  
        for (i = 0; step1 > 0; step1 /= N) {
  
            // Each time a power can be used
            // count how many times
            // it can be used
            if (i + step1 < M && arr[i + step1] <= target) {
                for (times = 1; step2 > 0; step2 >>= 1)
                    if (i + (step1 * (times + step2)) < M
                        && arr[i
                               + (step1 * (times + step2))]
                               <= target)
                        times += step2;
  
                step2 = PowerOf2;
  
                // Add to final result
                // how many times
                // can the power be used
                i += times * step1;
            }
        }
        
        // Return the index
        // if the element is present in array
        // else return -1
        return arr[i] == target ? i : -1;
    }
  
    // Driver code
    public static void main(String args[])
    {
        int[] arr = { 1, 4, 5, 8, 11, 15, 21, 45, 70, 100 };
        int target = 45, M = 10;
        int answer = Numeric_Base_Search(arr, M, target);
        System.out.println(answer);
    }
}
  
// This code is contributed by Saurabh Jaiswal


Python3
# Python code for the above approach
N = 3
PowerOf2 = 4
  
def Numeric_Base_Search(arr, M, target):
    i = None
    step1 = None
    step2 = PowerOf2
    times = None
  
    # Find the first power of N
    # greater than the array size
    step1 = 1
    while(step1 < M):
        step1 *= N
  
    i = 0
    while(step1):
        step1 = step1 // N
  
        # Each time a power can be used
        # count how many times
        # it can be used
        if (i + step1 < M and arr[i + step1] <= target):
            times=1
            while(step2):
                step2 >>= 1
                if (i + (step1 * (times + step2)) < M and arr[i + (step1 * (times + step2))] <= target):
                    times += step2;
  
            step2 = PowerOf2;
  
            # Add to final result
            # how many times
            # can the power be used
            i += times * step1
  
    # Return the index
    # if the element is present in array
    # else return -1
    return i if arr[i] == target else -1
  
   # Driver code
arr = [1, 4, 5, 8, 11, 15, 21, 45, 70, 100]
target = 45
M = 10
answer = Numeric_Base_Search(arr, M, target)
print(answer)
  
  # This code is contributed by Saurabh Jaiswal


C#
// C# code to implement the above approach
using System;
class GFG {
  
    static int N = 3;
    static int PowerOf2 = 4;
  
    static int Numeric_Base_Search(int[] arr, int M,
                                   int target)
    {
        int i, step1, step2 = PowerOf2, times;
  
        // Find the first power of N
        // greater than the array size
        for (step1 = 1; step1 < M; step1 *= N)
            ;
  
        for (i = 0; step1 > 0; step1 /= N) {
  
            // Each time a power can be used
            // count how many times
            // it can be used
            if (i + step1 < M && arr[i + step1] <= target) {
                for (times = 1; step2 > 0; step2 >>= 1)
                    if (i + (step1 * (times + step2)) < M
                        && arr[i
                               + (step1 * (times + step2))]
                               <= target)
                        times += step2;
  
                step2 = PowerOf2;
  
                // Add to final result
                // how many times
                // can the power be used
                i += times * step1;
            }
        }
        // Return the index
        // if the element is present in array
        // else return -1
        return arr[i] == target ? i : -1;
    }
  
    // Driver code
    public static void Main()
    {
        int[] arr = { 1, 4, 5, 8, 11, 15, 21, 45, 70, 100 };
        int target = 45, M = 10;
        int answer = Numeric_Base_Search(arr, M, target);
        Console.WriteLine(answer);
    }
}
  
// This code is contributed by ukasp.


Javascript



输出
7

时间复杂度: O(log N M * 记录2 N)
辅助空间: O(1)