给定一个代表字符串的大字符数组,使得所有结尾的非字符串字符都以’\ 0’结尾,即,所有的前导字符均为字符串字符,所有结尾的均为’\ 0’并且没有垃圾字符。编写一个有效的函数来查找此类字符串的长度。
例子:
Input: str[] = {'g', 'e', 'e', 'k', '\0', '\0', '\0', '\0', '\0', '\0'}
n = 10 // Total no. of characters including \0's
Output: Length of string is 4
Input: str[] = {'g', 'e', 'e', 'k', 's', 'q', 'u', 'i', 'z', '\0', '\0',
'\0', '\0', '\0', '\0', '\0'}
n = 15
Output: Length of string is 9
一个简单的解决方案是像普通的strlen函数一样继续读取字符,直到打到’\ 0’。标准strlen的时间复杂度为O(n)。
由于所有结尾字符均为“ \ 0”,因此我们可以使用二进制搜索。
通过将中间两个元素与’\ 0’进行比较,我们可以决定是否需要对左半部分或右半部分进行递归。
如果其中一个是\ 0,那么我们发现了第一个匹配项。
否则,如果两个元素均为“ \ 0”,则需要移到左半部分。
否则(当中间元素都不为\ 0时),我们需要移至右半部分。
下面是上述思想的C实现。
// A Binary Search based implementation of strlen when all non-string
// characters are \0
#include
/* if \0 is present in str[] then returns the index of FIRST occurrence
of \0 in str[low..high], otherwise returns -1 */
int firstZero(char str[], int low, int high)
{
if (high >= low)
{
// Check if mid element is first '\0'
int mid = low + (high - low)/2;
if (( mid == 0 || str[mid-1] != '\0') && str[mid] == '\0')
return mid;
if (str[mid] != '\0') // If mid element is not '\0'
return firstZero(str, (mid + 1), high);
else // If mid element is '\0', but not first '\0'
return firstZero(str, low, (mid -1));
}
return -1;
}
// This function mainly calls firstZero to find length.
int myStrlen(char str[], int n)
{
// Find index of first zero in given stray
int first = firstZero(str, 0, n-1);
// If '\0' is not present at all, return n
if (first == -1)
return n;
return first;
}
/* Driver program to check above functions */
int main()
{
char str[] = {'g', 'e', 'e', 'k', 's', 'q', 'u', 'i', 'z', '\0', '\0',
'\0', '\0', '\0', '\0', '\0'};
int n = sizeof(str)/sizeof(str[0]);
printf("Length of string is %d", myStrlen(str, n));
return 0;
}
输出:
Length of string is 9
这个想法类似于下面的帖子。我们对“ \ 0”的第一个匹配项进行二进制搜索。
找出零
计算排序数组中的出现次数
上述解决方案的时间复杂度为O(Logn),使用的算法范式为分而治之。
想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。