库函数strspn的定义是:
size_t strspn(const char *str, const char *chars)
/*Return number of leading characters at the beginning of the string str which are all members of string chars.*/
e.g。如果'str'是“fecxdy”而'chars'是“abcdef”那么函数将返回3,因为'f','e'和'c'都出现在'chars'中的某个地方,给出'str'的3个主要字符'和'x'是'str'的第一个字符,它不是'chars'的成员。
有人可以帮助我在'C'中编写strspn的实现。我可以从实现中调用的唯一库函数是strlen。
答案 0 :(得分:6)
基本思想是逐步遍历字符串,一次一个字符,并测试它是否在字符集中。如果不是,请停止并返回答案。在伪代码中,这看起来像:
count = 0
for each character c in str
if c is not in chars
break
count++
return count
if c is not in chars
测试可以通过迭代chars
的所有字符并测试c
是否匹配任何字符来实现。请注意,这不是最快的实现,因为它涉及单步执行chars
中每个字符的str
字符串。更快的实现将使用查找表来测试c is not in chars
。
答案 1 :(得分:2)
我认为这应该很快
size_t strspn(const char *str, const char *chars){
unsigned char ta[32]={0};
unsigned i,cnt=0;
for(i=0;chars[i];++i)
ta[chars[i]>>3]|=0x1<<(chars[i]%8);
for(i=0;str[i];++i)
if((ta[str[i]]>>(str[i]%8))&0x1) break;
return cnt-1;
}
答案 2 :(得分:1)
我在参加旧考试时发现了这个问题。您不能使用索引或任何标准函数。这是我尝试解决方案:
#include <stdio.h>
size_t myStrspn(const char *str1, const char *str2){
size_t i,j;
i=0;
while(*(str1+i)){
j=0;
while(*(str2+j)){
if(*(str1+i) == *(str2+j)){
break; //Found a match.
}
j++;
}
if(!*(str2+j)){
return i; //No match found.
}
i++;
}
return i;
}
void main(){
char s[] = "7803 Elm St.";
int n = 0;
n = myStrspn(s,"1234567890");
printf("The number length is %d. \n",n);
}
以下是考试的解决方案:
#include<stdio.h>
size_t strspn(const char* cs, const char* ct) {
size_t n;
const char* p;
for(n=0; *cs; cs++, n++) {
for(p=ct; *p && *p != *cs; p++)
;
if (!*p)
break;
}
return n;
}
For循环让它变得更紧凑。
答案 3 :(得分:1)
int my_strspn(const char *str1,const char *str2){
int i,k,counter=0;
for(i=0;str1[i]!='\0';i++){
if(counter != i) break;
for(k=0;str1[k]!='\0';k++){
if(str1[i]==str2[k])
counter++;
}
}
return counter;
}
答案 4 :(得分:0)
过去几年没有接触过C编译器。从头到尾,这样的事情应该有效:
int spn = 0;
while(*str++ != '\0')
{
char *hay = chars;
bool match = false;
while(*hay++ != '\0')
{
if(*hay == *str)
{
match = true;
break;
}
}
if(match)
spn++;
else
return spn;
}
return spn;
答案 5 :(得分:0)
好吧,为我的操作系统实现一个标准库,这是我的解决方案(C ++)。
setHeight()
答案 6 :(得分:0)
只要在第二个字符串中找到相应的字符,strspn()
的天真的实现就会在第一个字符串上进行迭代:
#include <string.h>
size_t strspn(const char *str, const char *chars) {
size_t i = 0;
while (str[i] && strchr(chars, str[i]))
i++;
return i;
}
鉴于不允许您调用strchr()
,这是一个简单的本机实现:
size_t strspn(const char *str, const char *chars) {
size_t i, j;
for (i = 0; str[i] != '\0'; i++) {
for (j = 0; chars[j] != str[i]; j++) {
if (chars[j] == '\0')
return i; // char not found, return index so far
}
}
return i; // complete string matches, return length
}
重复扫描第二个字符串可能会很昂贵。这是一种根据chars
的长度结合不同方法的替代方法,假设8位字节:
size_t strspn(const char *str, const char *chars) {
size_t i = 0;
char c = chars[0];
if (c != '\0') { // if second string is empty, return 0
if (chars[1] == '\0') {
// second string has single char, use a simple loop
while (str[i] == c)
i++;
} else {
// second string has more characters, construct a bitmap
unsigned char x, bits[256 / 8] = { 0 };
for (i = 0; (x = chars[i]) != '\0'; i++)
bits[x >> 3] |= 1 << (x & 7);
// iterate while characters are found in the bitmap
for (i = 0; (x = str[i]), (bits[x >> 3] & (1 << (x & 7))); i++)
continue;
}
}
return i;
}
答案 7 :(得分:0)
为所有可能的ASCII字符创建一个查找表(一个穷人的表),然后只查找str
中的每个字符。这是最糟糕的情况O(max(N,M))
,其中N
是str
中的字符数,M
是chars
中的字符数。
#include <string.h>
size_t strspn(const char *str, const char *chars) {
int i;
char ch[256] = {0};
for (i = 0; i < strlen(chars); i++) {
ch[chars[i]] = 1;
}
for (i = 0; i < strlen(str); i++) {
if (ch[str[i]] == 0) {
break;
}
}
return i;
}
这也可以完全不使用strlen
来解决,假设两个字符串都以零结尾。该解决方案的缺点是查找表需要256个字节的内存。