执行strspn()

时间:2009-05-02 01:24:51

标签: c

库函数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。

8 个答案:

答案 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)),其中Nstr中的字符数,Mchars中的字符数。

#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个字节的内存。