使用二进制搜索在 C 中查找交错序列

Posted

技术标签:

【中文标题】使用二进制搜索在 C 中查找交错序列【英文标题】:Use binary search to find interleaving sequence in C 【发布时间】:2019-03-11 12:53:20 【问题描述】:

我有两个数组,A 和 X,其中 A >= X。我想找到 X^i 的最大交织因子 i,使得 X^i 是 A 的子序列。例如,如果 A = [4 ,3,2,1,4,3,2,1,4,3,2,1,4,3,2,1],并且 X = [1,2,3],则 i = 1,因为 X ^1 = [1,2,3] 并且该序列在 A 中。我的程序应该使用二进制搜索来找到这个最大交织因子 i 并跟踪每次迭代是否是 A 的序列。所以使用二进制搜索上面的例子,我将开始 = 3(A/X = 6 时尽可能最大),并且 X^3 = [1,1,1,2,2,2,3,3,3] 这不是一个序列在 A.

到目前为止,这是我的代码:

#include <stdio.h>
#include <stdlib.h>

void create_initial_arrays(int size_a, int *A, int size_x, int *X);
void binary_search(int size_a, int * A, int size_x, int *X, int max_i, int min_i);

int main()
    int size_a, size_x;
    scanf("%d", &size_a);
    scanf("%d", &size_x);

    int max_i = size_a / size_x;
    int min_i = 0;

    printf("Max: %d\n", max_i);

    int *A = (int*) malloc(size_a *sizeof(int));
    int *X = (int*) malloc(size_x *sizeof(int));

    create_initial_arrays(size_a, A, size_x, X);

    printf("Old X: ");
    for(int i = 0; i < size_x; i++)
        printf("%d ", X[i]);
    
    printf("\n");

    binary_search(size_a, A, size_x, X, max_i, min_i); //practice reallocating size of array


    //for(int i = 0; i < size_x; i++)
      //  printf("%d ", A[i]);
    //





void create_initial_arrays(int size_a, int *A, int size_x, int *X)
    int i, throwaway;

    for(i = 0; i < size_a; i++)
        scanf("%d", &A[i]);
    

    scanf("%d", &throwaway);

    for(i = 0; i < size_x; i++)
        scanf("%d", &X[i]);
    

    scanf("%d", &throwaway);




void binary_search(int size_a, int * A, int size_x, int *X, int max_i, int min_i)

    int i, j, k, count = 0, max_repeat = 0;

    while(min_i <= max_i)

    int repeats = (max_i + min_i)/2;

    printf("\n");

    int * temp = realloc(X, size_x * sizeof(int) * repeats);
    X = temp;

    for(k = 0; k < size_x; ++k)
        int idx = size_x - k -1;
        temp = &X[idx];
        for(j = 0; j < repeats; ++j)
            X[idx * repeats + j] = *temp;
        
    

    printf("New X: ");
        for(i = 0; i < size_x * repeats; i++)
            printf("%d ", X[i]);
        

    for(i = 0; i < size_x * repeats; i++)
        for(j = 0; j < size_a; j++)
            if(A[j] == X[i])
                count++;
                i++;
            
        
    

    if (count == size_x * repeats)
        printf("Low: %d Mid %d High % d Passes\n", min_i, repeats, max_i);
        min_i = repeats + 1;
        max_repeat++;
    
    else
        printf("Low: %d Mid %d High % d Fails\n", min_i, repeats, max_i);
        max_i = repeats - 1;
    

    printf("Max repeat: %d", max_repeat);

这是我当前的输出:

New X: 1 1 1 2 2 2 3 3 3 Low: 0 Mid 3 High  6 Fails

New X: 1 1 1 Low: 0 Mid 1 High  2 Fails

New X: Low: 0 Mid 0 High  0 Fails

我期待这个:

New X: 1 1 1 2 2 2 3 3 3 Low: 0 Mid 3 High  6 Fails

New X: 1 2 3 Low: 0 Mid 1 High  2 Passes

New X: Low: 2 Mid 2 High  2 Fails

Max i = 1.

意思是,我的代码在第二次迭代中没有创建正确的数组。 X^1 应该等于 [1,2,3] 而不是 [1,1,1]。为什么它在第二次迭代时没有正确创建数组,但在第一次迭代时却创建了?

【问题讨论】:

您需要保留原始 X 数组的副本。计算新 X 的代码仅在 X 从原始扩展时才有效。 【参考方案1】:

为什么在第二次迭代时没有正确创建数组,但在第一次迭代时却创建了?

在第一个循环中,您将X1, 2, 3 更改为1, 1, 1, 2, 2, 2, 3, 3, 3,方法是重复 first 数字 3 次,重复 second 数字3 次并重复 第三个 数字 3 次。

在第二个循环中,您从X 开始,即1, 1, 1, 2, 2, 2, 3, 3, 3。现在您通过重复 第一个 数字 1 次、重复 第二 数字 1 次和重复 第三 数字 1 次来构造一个新的 X .

第一个、第二个和第三个数字都是1,你最终得到1, 1, 1

换句话说:您的第一个循环更改了X,因此您的第二个循环为X 使用了另一个值,而不是第一个循环。因此,第二个循环为X 产生了一个意外的值

【讨论】:

我明白你在说什么,我知道我需要另一个数组来保存原始数组。我真的不知道如何解决它。我实际上是在尝试使用 temp 变量保存原始文件。我需要在 X 上重新出现扩展,然后在每次迭代中进行二进制搜索。你能告诉我怎么做吗?此外,看起来我的二进制搜索仍然失败。 [1,1,1],即使不正确,仍应通过。 @Rahme 这个问题的解决方案很简单。只是不要更改X。而是在temp 上进行工作。解决此问题后,您可以针对遇到的任何其他问题提出新问题。一个问题 -> 一个问题。另一个问题 -> 另一个问题。 所以如果我取出 X = temp 行,我会得到一个 malloc 内存错误。如何将行 X[idx * repeats + j] = *temp 更改为 temp[idx * repeats + j] = ?? @Rahme 类似:temp[idx * repeats + j] = X[…]; BTW:检查你最后的if 声明! else 似乎错过了一些 @Rahme Like: ` for(k = 0; k

以上是关于使用二进制搜索在 C 中查找交错序列的主要内容,如果未能解决你的问题,请参考以下文章

使用二进制搜索在数组中查找数字的位置

在JavaScript中查找整数的二进制表示中最长的零序列?

在 Python 中交错两个十进制数字

如何在数据库索引中使用二进制搜索

在Python中的二进制搜索算法中查找数组的中间索引值

java 501.在二进制搜索Tree.java中查找模式