C语言常见字符串面试题

一些常用字符串操作函数的内部实现 

memset:
  1. /*
  2.  * memset - Fill a region of memory with the given value
  3.  * @s: Pointer to the start of the area.
  4.  * @c: The byte to fill the area with
  5.  * @count: The size of the area.
  6.  */
  7. void *memset(void *s, int c, size_t count)
  8. {
  9.     char *xs = s;

  10.     while (count--)
  11.         *xs++ = c;
  12.     return s;
  13. }

memcpy:
  1. /*
  2. * memcpy - Copy one area of memory to another
  3. * @dest: Where to copy to
  4. * @src: Where to copy from
  5. * @count: The size of the area.
  6. */
  7. void *memcpy(void *dest, const void *src, size_t count)
  8. {
  9. char *tmp = dest;
  10. const char *s = src;
  11. while (count--)
  12. *tmp++ = *s++;
  13. return dest;
  14. }

memmove:
  1. /*
  2.  * memmove - Copy one area of memory to another
  3.  * @dest: Where to copy to
  4.  * @src: Where to copy from
  5.  * @count: The size of the area.
  6.  * Unlike memcpy(), memmove() copes with overlapping areas.
  7.  */
  8. void *memmove(void *dest, const void *src, size_t count)
  9. {
  10.     char *tmp;
  11.     const char *s;

  12.     if (dest <= src) {
  13.         tmp = dest;
  14.         s = src;
  15.         while (count--)
  16.             *tmp++ = *s++;
  17.     } else {
  18.         tmp = dest;
  19.         tmp += count;
  20.         s = src;
  21.         s += count;
  22.         while (count--)
  23.             *--tmp = *--s;
  24.     }
  25.     return dest;
  26. }

memcmp:
  1. /*
  2.  * memcmp - Compare two areas of memory
  3.  * @cs: One area of memory
  4.  * @ct: Another area of memory
  5.  * @count: The size of the area.
  6.  */
  7. int memcmp(const void *cs, const void *ct, size_t count)
  8. {
  9.     const unsigned char *su1, *su2;
  10.     int res = 0;

  11.     for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
  12.         if ((res = *su1 - *su2) != 0)
  13.             break;
  14.     return res;
  15. }

strcpy:
  1. /*
  2.  * strcpy - Copy a %NUL terminated string
  3.  * @dest: Where to copy the string to
  4.  * @src: Where to copy the string from
  5.  */
  6. char *strcpy(char *dest, const char *src)
  7. {
  8.     char *tmp = dest;

  9.     while ((*dest++ = *src++) != '\0');

  10.     return tmp;
  11. }

strncpy:
  1. /*
  2.  * strncpy - Copy a length-limited, %NUL-terminated string
  3.  * @dest: Where to copy the string to
  4.  * @src: Where to copy the string from
  5.  * @count: The maximum number of bytes to copy
  6.  *
  7.  * The result is not %NUL-terminated if the source exceeds
  8.  * @count bytes.
  9.  *
  10.  * In the case where the length of @src is less than that of
  11.  * count, the remainder of @dest will be padded with %NUL.
  12.  */
  13. char *strncpy(char *dest, const char *src, size_t count)
  14. {
  15.     char *tmp = dest;

  16.     while (count) {
  17.         if ((*tmp = *src) != 0)
  18.             src++;
  19.         tmp++;
  20.         count--;
  21.     }

  22.     return dest;
  23. }

strcat:
  1. /*
  2.  * strcat - Append one %NUL-terminated string to another
  3.  * @dest: The string to be appended to
  4.  * @src: The string to append to it
  5.  */
  6. char *strcat(char *dest, const char *src)
  7. {
  8.     char *tmp = dest;

  9.     while (*dest)
  10.         dest++;
  11.     while ((*dest++ = *src++) != '\0');

  12.     return tmp;
  13. }

strncat:
  1. /*
  2.  * strncat - Append a length-limited, %NUL-terminated string to another
  3.  * @dest: The string to be appended to
  4.  * @src: The string to append to it
  5.  * @count: The maximum numbers of bytes to copy
  6.  *
  7.  * Note that in contrast to strncpy(), strncat() ensures the result is
  8.  * terminated.
  9.  */
  10. char *strncat(char *dest, const char *src, size_t count)
  11. {
  12.     char *tmp = dest;

  13.     if (count) {
  14.         while (*dest)
  15.             dest++;
  16.         while ((*dest++ = *src++) != 0) {
  17.             if (--count == 0) {
  18.                 *dest = '\0';
  19.                 break;
  20.             }
  21.         }
  22.     }

  23.     return tmp;
  24. }

strcmp:
  1. /*
  2.  * strcmp - Compare two strings
  3.  * @cs: One string
  4.  * @ct: Another string
  5.  */
  6. int strcmp(const char *cs, const char *ct)
  7. {
  8.     unsigned char c1, c2;

  9.     while (1) {
  10.         c1 = *cs++;
  11.         c2 = *ct++;
  12.         if (c1 != c2)
  13.             return c1 < c2 ? -: 1;
  14.         if (!c1)
  15.             break;
  16.     }

  17.     return 0;
  18. }

strncmp:
  1. /*
  2.  * strncmp - Compare two length-limited strings
  3.  * @cs: One string
  4.  * @ct: Another string
  5.  * @count: The maximum number of bytes to compare
  6.  */
  7. int strncmp(const char *cs, const char *ct, size_t count)
  8. {
  9.     unsigned char c1, c2;

  10.     while (count) {
  11.         c1 = *cs++;
  12.         c2 = *ct++;
  13.         if (c1 != c2)
  14.             return c1 < c2 ? -: 1;
  15.         if (!c1)
  16.             break;
  17.         count--;
  18.     }

  19.     return 0;
  20. }

strchr:
  1. /*
  2.  * strchr - Find the first occurrence of a character in a string
  3.  * @s: The string to be searched
  4.  * @c: The character to search for
  5.  */
  6. char *strchr(const char *s, int c)
  7. {
  8.     for (; *!= (char)c; ++s)
  9.         if (*== '\0')
  10.             return NULL;

  11.     return (char *)s;
  12. }

strlen:
  1. /*
  2.  * strlen - Find the length of a string
  3.  * @s: The string to be sized
  4.  */
  5. size_t strlen(const char *s)
  6. {
  7.     const char *sc;

  8.     for (sc = s; *sc != '\0'; ++sc);

  9.     return sc - s;
  10. }

strnlen:
  1. /*
  2.  * strnlen - Find the length of a length-limited string
  3.  * @s: The string to be sized
  4.  * @count: The maximum number of bytes to search
  5.  */
  6. size_t strnlen(const char *s, size_t count)
  7. {
  8.     const char *sc;

  9.     for (sc = s; count-- && *sc != '\0'; ++sc);

  10.     return sc - s;
  11. }

strsep:
  1. /*
  2.  * strsep - Split a string into tokens
  3.  * @s: The string to be searched
  4.  * @ct: The characters to search for
  5.  *
  6.  * strsep() updates @s to point after the token, ready for the next call.
  7.  */
  8. char *strsep(char **s, const char *ct)
  9. {
  10.     char *sbegin = *s;
  11.     char *end;

  12.     if (sbegin == NULL)
  13.         return NULL;

  14.     end = strpbrk(sbegin, ct);
  15.     if (end)
  16.         *end++ = '\0';
  17.     *= end;

  18.     return sbegin;
  19. }

strstr:
  1. /*
  2.  * strstr - Find the first substring in a %NUL terminated string
  3.  * @s1: The string to be searched
  4.  * @s2: The string to search for
  5.  */
  6. char *strstr(const char *s1, const char *s2)
  7. {
  8.     int l1, l2;

  9.     l2 = strlen(s2);
  10.     if (!l2)
  11.         return (char *)s1;
  12.     l1 = strlen(s1);
  13.     while (l1 >= l2) {
  14.         l1--;
  15.         if (!memcmp(s1, s2, l2))
  16.             return (char *)s1;
  17.         s1++;
  18.     }

  19.     return NULL;
  20. }
常见字符串面试题:
1)写出在母串中查找子串出现次数的代码.
[cpp]  view plain  copy
  1. int count1(char* str,char* s)  
  2. {  
  3.     char* s1;  
  4.     char* s2;  
  5.     int count = 0;  
  6.     while(*str!='/0')  
  7.     {  
  8.         s1 = str;  
  9.         s2 = s;  
  10.         while(*s2 == *s1&&(*s2!='/0')&&(*s1!='0'))  
  11.         {  
  12.             s2++;  
  13.             s1++;  
  14.         }  
  15.         if(*s2 == '/0')  
  16.             count++;  
  17.         str++;  
  18.     }  
  19.     return count;  
  20. }  
2)查找第一个匹配子串位置,如果返回的是s1长度len1表示没有找到
[cpp]  view plain  copy
  1. size_t find(char* s1,char* s2)  
  2.     {  
  3.         size_t i=0;  
  4.          size_t len1 = strlen(s1)  
  5.         size_t len2 = strlen(s2);  
  6.         if(len1-len2<0) return len1;  
  7.         for(;i<len1-len2;i++)  
  8.         {  
  9.             size_t m = i;  
  10.             for(size_t j=0;j<len2;j++)  
  11.             {  
  12.                 if(s1[m]!=s2[j])  
  13.                     break;  
  14.                 m++;  
  15.             }  
  16.             if(j==len)  
  17.                 break;  
  18.         }  
  19.         return i<len1-len2?i:len1;  
  20.     }  

3)实现strcpy函数
[cpp]  view plain  copy
  1. char *strcpy(char *destination, const char *source)   
  2. {   
  3.     assert(destination!=NULL&&source!=NULL);  
  4.     char* target = destinaton;  
  5.     while(*destinaton++=*source++);   
  6.     return target ;   
  7. }   
出现次数相当频繁
4)实现strcmp函数
[cpp]  view plain  copy
  1. int strcmp11(char* l,char* r)  
  2. {  
  3.     assert(l!=0&&r!=0);  
  4.     while(*l == *r &&*l != '/0') l++,r++;  
  5.     if(*l > *r)  
  6.         return 1;  
  7.     else if(*l == *r)  
  8.         return 0;  
  9.     return -1;  
  10. }  
5) 实现字符串翻转
[cpp]  view plain  copy
  1. void reserve(char* str)  
  2. {  
  3.     assert(str != NULL);  
  4.     char * p1 = str;  
  5.     char * p2 = str-1;  
  6.     while(*++p2);         //一般要求不能使用strlen  
  7.     p2 -= 1;  
  8.     while(p1<p2)  
  9.     {  
  10.         char c = *p1;  
  11.         *p1++ = *p2;  
  12.         *p2-- = c;  
  13.    }  
  14. }  
6)、用指针的方法,将字符串“ABCD1234efgh”前后对调显示
//不要用strlen求字符串长度,这样就没分了
代码如下:
    
[cpp]  view plain  copy
  1. char str123[] = "ABCD1234efgh";  
  2.     char * p1 = str123;  
  3.     char * p2 = str123-1;  
  4.     while(*++p2);  
  5.     p2 -= 1;  
  6.     while(p1<p2)  
  7.     {  
  8.         char c = *p1;  
  9.         *p1++ = *p2;  
  10.         *p2-- = c;  
  11.     }  

7) 给定字符串A和B,输出A和B中的最大公共子串。比如A="aocdfe" B="pmcdfa" 则输出"cdf"

[cpp]  view plain  copy
  1. #i nclude<stdio.h>  
  2. #i nclude<stdlib.h>  
  3. #i nclude<string.h>  
  4. char *commanstring(char shortstring[], char longstring[])  
  5. {  
  6.     int i, j;  
  7.     char *substring=malloc(256);  
  8.     if(strstr(longstring, shortstring)!=NULL)              //如果……,那么返回shortstring  
  9.         return shortstring;   
  10.     for(i=strlen(shortstring)-1;i>0; i--)                 //否则,开始循环计算  
  11.     {  
  12.         for(j=0; j<=strlen(shortstring)-i; j++)  
  13.         {  
  14.             memcpy(substring, &shortstring[j], i);  
  15.             substring[i]='/0';  
  16.             if(strstr(longstring, substring)!=NULL)  
  17.             return substring;  
  18.         }  
  19.     }  
  20.     return NULL;  
  21. }  
  22.   
  23. main()  
  24. {  
  25.     char *str1=malloc(256);  
  26.     char *str2=malloc(256);  
  27.     char *comman=NULL;  
  28.     gets(str1);  
  29.     gets(str2);  
  30.     if(strlen(str1)>strlen(str2))                         //将短的字符串放前面  
  31.         comman=commanstring(str2, str1);  
  32.     else  
  33.         comman=commanstring(str1, str2);  
  34.     printf("the longest comman string is: %s/n", comman);  
  35. }  

8) 判断一个字符串是不是回文

[cpp]  view plain  copy
  1. int IsReverseStr(char *str)  
  2. {  
  3.     int i,j;  
  4.     int found=1;  
  5.     if(str==NULL)  
  6.         return -1;  
  7.     char* p = str-1;  
  8.     while(*++p!= '/0');  
  9.     --p;  
  10.     while(*str==*p&&str<p) str++,p--;  
  11.     if(str < p)  
  12.         found = 0;  
  13.     return found;  
  14. }  

9)写函数完成内存的拷贝
[cpp]  view plain  copy
  1. void* memcpy( void *dst, const void *src, unsigned int len )  
  2. {  
  3.     register char *d;  
  4.     register char *s;  
  5.     if (len == 0)  
  6.         return dst;  
  7.     if ( dst > src )   //考虑覆盖情况  
  8.     {  
  9.         d = (char *)dst + len - 1;  
  10.         s = (char *)src + len - 1;  
  11.         while ( len >= 4 )   //循环展开,提高执行效率  
  12.         {  
  13.             *d-- = *s--;  
  14.             *d-- = *s--;  
  15.             *d-- = *s--;  
  16.             *d-- = *s--;  
  17.             len -= 4;  
  18.         }  
  19.         while ( len-- )   
  20.         {  
  21.             *d-- = *s--;  
  22.         }  
  23.     }   
  24.     else if ( dst < src )   
  25.     {  
  26.         d = (char *)dst;  
  27.         s = (char *)src;  
  28.         while ( len >= 4 )  
  29.         {  
  30.             *d++ = *s++;  
  31.             *d++ = *s++;  
  32.             *d++ = *s++;  
  33.             *d++ = *s++;  
  34.             len -= 4;  
  35.         }  
  36.         while ( len-- )  
  37.         {  
  38.             *d++ = *s++;  
  39.         }  
  40.     }  
  41.     return dst;  
  42. }  
出现次数相当频繁

10)写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)
功能:
在字符串中找出连续最长的数字串,并把这个串的长度返回,并把这个最长数字串付给其中一个函数参数outputstr所指内存。例如:"abcd12345ed125ss123456789"的首地址传给intputstr后,函数将返回9,outputstr所指的值为123456789

[cpp]  view plain  copy
  1. int continumax(char *outputstr, char *inputstr)  
  2. {  
  3.     char *in = inputstr, *out = outputstr, *temp, *final;  
  4.     int count = 0, maxlen = 0;  
  5.     while( *in != '/0' )  
  6.     {  
  7.         if( *in > 47 && *in < 58 )  
  8.         {  
  9.             for(temp = in; *in > 47 && *in < 58 ; in++ )  
  10.             count++;  
  11.         }  
  12.     else  
  13.     in++;  
  14.     if( maxlen < count )  
  15.     {  
  16.         maxlen = count;  
  17.         count = 0;  
  18.         final = temp;  
  19.     }  
  20.     }  
  21.     for(int i = 0; i < maxlen; i++)  
  22.     {  
  23.         *out = *final;  
  24.         out++;  
  25.         final++;  
  26.     }  
  27.     *out = '/0';  
  28.     return maxlen;  
  29. }  

11) 编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串是由同一字符组成的。
[cpp]  view plain  copy
  1. char * search(char *cpSource, char ch)  
  2. {  
  3.          char *cpTemp=NULL, *cpDest=NULL;  
  4.          int iTemp, iCount=0;  
  5.          while(*cpSource)  
  6.          {  
  7.                  if(*cpSource == ch)  
  8.                  {  
  9.                           iTemp = 0;  
  10.                           cpTemp = cpSource;  
  11.                           while(*cpSource == ch)   
  12.                                    ++iTemp, ++cpSource;  
  13.                           if(iTemp > iCount)   
  14.                                 iCount = iTemp, cpDest = cpTemp;  
  15.                         if(!*cpSource)   
  16.                             break;  
  17.                  }  
  18.                  ++cpSource;  
  19.      }  
  20.      return cpDest;  
  21. }        
排序算法:

冒泡排序: 出现次数相当频繁

[cpp]  view plain  copy
  1. void buble(int *a,int n)  
  2. {  
  3.     for(int i=0;i<n;i++)  
  4.     {  
  5.         for(int j=1;j<n-i;j++)  
  6.         {  
  7.             if(a[j]<a[j-1])  
  8.             {  
  9.                 int temp=a[j];  
  10.                 a[j] = a[j-1];  
  11.                 a[j-1] = temp;  
  12.             }  
  13.         }  
  14.     }  
  15. }  

插入排序:
[cpp]  view plain  copy
  1. void insertsort(int* a,int n)  
  2. {  
  3.     int key;  
  4.     for(int j=1;j<n;j++)  
  5.     {  
  6.         key = a[j];  
  7.         for(int i=j-1;i>=0&&a[i]>key;i--)  
  8.         {  
  9.             a[i+1] = a[i];  
  10.         }  
  11.         a[i+1] = key;  
  12.     }  
  13. }  

将一个数字字符串转换为数字."1234" -->1234

[cpp]  view plain  copy
  1. int atoii(char* s)  
  2. {  
  3.     assert(s!=NULL);  
  4.     int num = 0;  
  5.     int temp;  
  6.     while(*s>'0' && *s<'9')  
  7.     {  
  8.         num *= 10;  
  9.         num += *s-'0';  
  10.         s++;  
  11.     }  
  12.     return num;  
  13. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值