2010年7月12日

strcpy

 

char *strcpy(char *dest, char *src) {
    
char *= src, *= dest;
    
do {
    } 
while (*(d++= *s++);

    
return dest;
}

 

 

posted @ 2010-07-12 16:25 庄冠华 阅读(3) 评论(0) 编辑

glibc 中的 strlen 高效实现

 

代码
#include <string.h>
#include 
<stdlib.h>

#undef strlen

/* Return the length of the null-terminated string STR.  Scan for
   the null terminator quickly by testing four bytes at a time.  
*/
size_t strlen(
const char *str) {
    
const char *char_ptr;
    
const unsigned long int *longword_ptr;
    unsigned 
long int longword, himagic, lomagic;

    
/* Handle the first few characters by reading one character at a time.
       Do this until CHAR_PTR is aligned on a longword boundary.  
*/
    
for (char_ptr = str; ((unsigned long int) char_ptr
            
& (sizeof (longword) - 1)) != 0;
            
++char_ptr)
        
if (*char_ptr == '\0')
            
return char_ptr - str;

    
/* All these elucidatory comments refer to 4-byte longwords,
       but the theory applies equally well to 8-byte longwords.  
*/

    longword_ptr 
= (unsigned long int *) char_ptr;

    
/* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
       the "holes."  Note that there is a hole just to the left of
       each byte, with an extra at the end:

       bits:  01111110 11111110 11111110 11111111
       bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD

       The 1-bits make sure that carries propagate to the next 0-bit.
       The 0-bits provide holes for carries to fall into.  
*/
    himagic 
= 0x80808080L;
    lomagic 
= 0x01010101L;
    
if (sizeof (longword) > 4) {
        
/* 64-bit version of the magic.  */
        
/* Do the shift in two steps to avoid a warning if long has 32 bits.  */
        himagic 
= ((himagic << 16<< 16| himagic;
        lomagic 
= ((lomagic << 16<< 16| lomagic;
    }
    
if (sizeof (longword) > 8)
        abort();

    
/* Instead of the traditional loop which tests each character,
       we will test a longword at a time.  The tricky part is testing
       if *any of the four* bytes in the longword in question are zero.  
*/
    
for (;;) {
        longword 
= *longword_ptr++;

        
if (((longword - lomagic) & ~longword & himagic) != 0) {
            
/* Which of the bytes was the zero?  If none of them were, it was
               a misfire; continue the search.  
*/

            
const char *cp = (const char *) (longword_ptr - 1);

            
if (cp[0== 0)
                
return cp - str;
            
if (cp[1== 0)
                
return cp - str + 1;
            
if (cp[2== 0)
                
return cp - str + 2;
            
if (cp[3== 0)
                
return cp - str + 3;
            
if (sizeof (longword) > 4) {
                
if (cp[4== 0)
                    
return cp - str + 4;
                
if (cp[5== 0)
                    
return cp - str + 5;
                
if (cp[6== 0)
                    
return cp - str + 6;
                
if (cp[7== 0)
                    
return cp - str + 7;
            }
        }
    }
}
/* 说明
(1) 一次判断一个字符直到内存对齐,如果在内存对齐之前就遇到'\0'则直接return,否则到(2);
(2) 一次读入并判断一个DWORD,如果此DWORD中没有为0的字节,则继续下一个DWORD,否则到(3);
(3) 到这里则说明DWORD中至少有一个字节为0,剩下的就是找出第一个为0的字节的位置然后return。
*/
 


 

 

posted @ 2010-07-12 15:34 庄冠华 阅读(34) 评论(0) 编辑

面试遇到的题目:strstr 子串查找

 

代码
char *strstr(char *buf, char *sub) 

{
    
char *bp, *sp;
    
if (!*sub)
        
return buf;
    
while (*buf) {
        bp 
= buf;
        sp 
= sub;
        
do {
            
if (!*sp)
                
return buf;
        } 
while (*bp++ == *sp++);
        buf 
+= 1;
    }
    
return 0;
}
更加高效的算法还有KMP算法

KMP是字符串匹配的高效算法。

它的基本思路是,对于模式串建立一个“失败转移表”(fail transform table)。设模式串为B,原串为A,也就是说,当A[i]!=B[j]的时候,A[i]可能与B[P[j]]匹配。P可以在事先对B进行一次“自匹配”以计算出来。

 

 

 

 

posted @ 2010-07-12 15:28 庄冠华 阅读(85) 评论(0) 编辑