【问题标题】:Why does this string binary search program can't search half up the data?为什么这个字符串二进制搜索程序不能搜索一半的数据?
【发布时间】:2020-04-03 20:10:09
【问题描述】:

一开始我以为程序运行良好,但是当我测试搜索“马”时,搜索失败。而且我注意到该程序最多只能搜索一半的数据。有谁知道为什么? 我已经添加了 qsort,但它仍然不会搜索下半部分数据。

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

int compare(const void *a, const void *b){

    const char *ia = (const char *)a;
    const char *ib = (const char *)b;

    return strcmp(ia, ib);
}

int main(int argc, char argv){

    char data[10][50]={"cow", "goat", "dog", "sheep", "chicken", "duck", "bird","fish", "bee", "horse"};
    int size1 = sizeof(data[0]);
    int n = sizeof(data) / size1;
    printf("%d\n\n", n);
    int i, j;
    bool check = false;
    char key[10];
    int low = 0;
    int high = n - 1;
    int mid;
    char temp;

    for(i = 0; i<n; i++){
        printf("%s\n", data[i]);
    }

    qsort(data, n, size1, compare);
    printf("=============\n\n");

    for(i = 0; i<n; i++){
        printf("%s\n", data[i]);
    }
    system("pause");
    printf("Search: "); scanf("%s", &key);
    fflush(stdin);

    while(low<=high){
        mid = (low + high) / 2;
        if(strcmp(key,data[mid])==0){
            printf("Data Found ! on index - %d\n", mid);
            break;
        } else if(strcmp(key,data[mid])<0){
            low = mid + 1;
        }else {
            high = mid - 1;
        }
    }

    if(low > high){
        printf("Data not found");
    }
    return 0;
}

【问题讨论】:

  • 二进制搜索用于排序数据。你的显然没有排序。
  • 我要补充一些问题,如何对字符串数据进行排序?是ASCII码吗?
  • 也不要将key 与data[mid] 比较两次。
  • @r3mainer 是的,这有助于对数据进行排序,但搜索仍然不起作用

标签: c binary-search


【解决方案1】:

使用qsort,您可以对字符串数组进行排序,这里的else if (strcmp(key, data[mid]) &lt; 0) 应该是&gt;,如下面的代码所示。否则您的搜索将无法进行。

static int myCompare(const void* a, const void* b)
{
    return strcmp(*(const char**)a, *(const char**)b);
}

int main()
{
    char* data [] = { 
        "cow", "goat", "dog", "sheep", "chicken", "duck", "bird","fish", "bee", "horse" 
    };
    int n = sizeof(data) / sizeof(data[0]);
    int i;

    qsort(data, n, sizeof(const char*), myCompare);
    char key[10];
    int low = 0;
    int high = n - 1;
    int mid;
    char temp;

    scanf("%s", key);
    fflush(stdin);

    while (low <= high) {
        mid = (low + high) / 2;
        int a = strcmp(key, data[mid]);
        if (a == 0) {
            printf("Data Found ! on index - %d\n", mid);
            break;
        }
        else if (a > 0) {
            low = mid + 1;
        }
        else { // or only else(no special need for else if
            high = mid - 1;
        }
    }

    if (low > high) {
        printf("Data not found");
    }
    return 0;
}

【讨论】:

  • 什么!非常感谢,等等,所以 (strcmp(a,b)
  • @ChristianHalim 随意,无需感谢,但如果这个答案有帮助,请接受答案。
  • @ChristianHalim 确实如此,所以strcmp(key, data[mid]) &gt; 0 表示键大于中间值,因此您希望下一次搜索从中间点以上开始,low = mid +
  • @ChristianHalim 实际上在任何其他类型的二进制搜索中(不适用于字符串),就像这里一样,没有 '(strcmp(a,b)
  • @ChristianHalim 注意key 和data[mid] 的顺序。比较。
【解决方案2】:

和上面的 cmets 一样,二分查找是针对已排序的数据。你的显然没有排序。因此,首先,您必须对数据进行排序。排序数据的算法有很多,但是下面的代码,我使用了快速排序,这也可以帮助你理解你的搜索算法。

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

void swap(char ** a, char ** b) { 
    char * t = *a;
    *a = *b;
    *b = t;
}


/* This function takes last element as pivot, places 
   the pivot element at its correct position in sorted 
    array, and places all smaller (smaller than pivot) 
   to left of pivot and all greater elements to right 
   of pivot */
int partition (char ** arr, int low, int high) { 
    char * pivot = arr[high];    // pivot 
    int i = (low - 1);  // Index of smaller element 

    for (int j = low; j <= high- 1; j++) { 
        // If current element is smaller than the pivot 
        if (strcmp(arr[j],pivot) < 0) { 
            i++;    // increment index of smaller element 
            swap(&arr[i], &arr[j]); 
        } 
    } 
    swap(&arr[i + 1], &arr[high]); 
    return (i + 1); 
}

/* arr[] --> Array to be sorted, 
   low  --> Starting index, 
   high  --> Ending index */
void quickSort(char **arr, int low, int high) { 
    if (low < high) { 
        /* pi is partitioning index, arr[p] is now 
           at right place */
        int pi = partition(arr, low, high); 

        // Separately sort elements before 
        // partition and after partition 
        quickSort(arr, low, pi - 1); 
        quickSort(arr, pi + 1, high); 
    } 
} 

int main(){

   char *a = "abc";
   char *b = "cdf";
   swap(&a, &b);
   printf("a = %s, b= %s\n", a, b);
   char * data[10]={"cow", "goat", "dog", "sheep", "chicken", "duck", "bird","fish", "bee", "horse"};
   quickSort(data, 0, 9);
   for(int i = 0; i < 10; i++) {
    printf("%s, ", data[i]);
   }

   return 0;
}

排序后,您可以使用您的搜索算法。

【讨论】:

  • 没有理由贴出自己的排序算法来回答这个问题,qsort的标准库实现就可以了。
  • 问题是在我更新排序代码期间编辑的,所以我不知道版本。这就是我发布自己的排序算法的原因。所以我认为,否决票对我来说是不公平的。我只是试着帮助他在搜索之前对数据进行排序。
  • 投反对票仅仅是因为您推荐您的代码而不是使用标准库,与 OP 的编辑无关。
  • 这是一个不错的排序算法。
猜你喜欢
  • 1970-01-01
  • 2023-03-24
  • 2021-11-19
  • 2020-09-27
  • 1970-01-01
  • 2018-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多