字符串数组按排序顺序给出,但它们之间可以包含任意数量的空字符串。我需要搜索该字符串数组中的字符串。如果找到string,则返回该索引,否则返回-1。
我使用strcmp()编写了下面的代码,该代码适用于没有NULL字符串的字符串数组。如何扩展它以适用于具有Null字符串的数组。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int search(char *arr[], char *strtofind, int l, int r)
{
int mid , val;
if(l <= r)
{
mid = (l+r)/2;
val = strcmp(strtofind, arr[mid]);
if(val == 0)
return mid;
else if(val > 0)
{
return search(arr, strtofind,mid+1,r);
}
else
{
return search(arr, strtofind, l, mid-1);
}
}
return -1;
}
int main(int argc, char** argv)
{
int idx;
//char *arr[] = {"STR1", "STR2","STR3","STR4","STR5","STR6","STR7"}; // WORKS HERE
char *arr[] = {"STR1", "STR2","STR3",NULL,"STR4",NULL,"STR5"}; // NOT WORKS HERE
idx = search(arr, "STR4", 0, 6);
printf("Found at = %d\n", idx);
printf("Will is Everything.");
return (EXIT_SUCCESS);
}
答案 0 :(得分:1)
更改比较代码。 NULL
中的arr[mid]
本质上是“跳过”此元素,因此比较需要线性寻找下一个或前一个元素。
为防止最坏情况导致代码混乱,请确保后续搜索列表的两半不会重新扫描一组NULL
元素mid
。请注意列表两端的NULL
。
最糟糕的情况是O(n*n)
,其中有很多NULL
。如果O(n*ln2(n))
很少见,则可以预期NULL
表现。
此外,不需要递归调用。见评论
int search(const char *arr[], const char *strtofind, int l, int r)
while (l <= r) {
int mid = (l+r)/2;
int right_min = mid + 1;
while (arr[mid] == NULL) {
// If entire left side and mid are NULL ...
if (mid == 0) {
return search(arr, strtofind, right_min, r);
// or { l = right_min; continue; }
}
mid--;
}
int cmp = strcmp(strtofind, arr[mid]);
if (cmp == 0) {
return mid;
}
if(val > 0) {
return search(arr, strtofind, right_min, r);
// or { l = right_min; continue; }
}
int left_max = mid - 1;
return search(arr, strtofind, l, left_max);
// or { r = left_max; }
}
return -1;
}
建议:使用const
。
如果arr[]
所有NULL
都在一端,则存在一种有效的方法。 O(n*ln2(n))
答案 1 :(得分:0)
这样的东西会跳过空值。一旦它达到空值,它就会转向线性搜索,但我想不出更好的方法。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int search(char arr[][20], char *strtofind, int l, int r)
{
int mid , val, down = 1, start;
if(l <= r)
{
mid = (l+r)/2;
start = mid;
while(0 == arr[mid])
{
if(down)
{
if(mid >= l)
{
mid--;
}
else
{
down = 0;
mid = start;
}
}
else
{
if(mid <= r)
{
mid++;
}
else
{
return -1;
}
}
}
val = strcmp(strtofind, arr[mid]);
if(val == 0)
return mid;
else if(val > 0)
{
return search(arr, strtofind,mid+1,r);
}
else
{
return search(arr, strtofind, l, mid-1);
}
}
return -1;
}
int main(int argc, char** argv)
{
int idx;
char arr[][20] = {"STR1", "STR2","STR3","STR4"};
int num = sizeof(arr)/sizeof(arr[0]);
idx = search(arr, "STR2", 0, num-1);
if(-1 != idx)
{
printf("Found at = %d\n", idx);
}
else
{
printf("Not found");
}
return (EXIT_SUCCESS);
}
答案 2 :(得分:0)
执行strcmp()时,请检查NULL。如果为NULL则转到that_index-1。它会起作用。