1:字符串查找
给定一个字符串A,要求在A中查找一个子串B。如A="ABCDF",要你在A中查找子串B=“CD”。
初步代码如下:
int strstr(char *string, char *substring)
{
if (string == NULL|| substring == NULL)
return -1;
int lenstr = strlen(string);
int lensub= strlen(substring);
if (lenstr < lensub)
return -1;
int len = lenstr - lensub;
for (int i = 0; i <= len; i++) //复杂度为O(m*n)
{
for (int j = 0; j < lensub; j++)
{
if (string[i+j] !=substring[j])
break;
}
if (j == lensub)
return i + 1;
}
return -1;
}
针对这个strstr的函数,我觉得有点小问题。我查了一下C标准库的源码,它给的声明是这样的,两个参数都有const:
char *strstr(const char *haystack_start, const char *needle_start)
而且标准库中没有调用strlen函数,因为假如你是标准库的设计者,strlen()函数还没设计出来,你怎么去计算两个字符串的长度?是不是只能通过指针移动来实现,我觉得这些都是微软要考察的地方。
此外:还有int lenstr=strlen(string);这是不安全的?strlen函数的返回类型是size_t型,也就是无符号整型,假如我的数组长度很长(假如是用堆分配的,可以很大很大),长过2的31次方减1的话,会发生一处,你这lenstr就会变成负值了,所以用size_t类型最保险。
2:字符查找
在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。代码如下:
char FirstNotRepeatChar(char * pString)
{
if(!pString) return '\0';
const int tableSize = 256;
int hashTable[tableSize] = {0}; //存入数组,并初始化为0
char * pHashKey = pString;
while(*(pHashKey) != '/0')
hashTable[*(pHashKey++)]++;
while(*pString != '/0')
{
if(hashTable[*pString] == 1)
return *pString;
pString++;
}
return '\0'; //没有找到满足条件的字符,退出
}
3:字符串拷贝
题目描述:要求实现库函数strcpy,
原型声明:extern char*strcpy(char *dest,char *src);
功能:把src所指由NULL结束的字符串复制到dest所指的数组中。
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。
分析:如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:
//2分
void strcpy( char *strDest, char *strSrc)
{
while( (*strDest++ = * strSrc++) !='/0' );
}
//4分
void strcpy( char *strDest, const char *strSrc )
{
//将源字符串加const,表明其为输入参数,加2分
while( (*strDest++ = * strSrc++) !='/0' );
}
//7分
void strcpy(char *strDest, const char *strSrc)
{
//对源地址和目的地址加非0断言,加3分
assert((strDest != NULL) && (strSrc != NULL) );
while( (*strDest++ = * strSrc++) !='/0' );
}
//10分
//为了实现链式操作,将目的地址返回,加3分!
char * strcpy( char *strDest, const char *strSrc )
{
assert((strDest != NULL) && (strSrc != NULL) );
char *address =strDest;
while( (*strDest++ = * strSrc++) !='/0' );
return address;
}
4:部分库函数的实现
char *strncpy(char *strDes, const char *strSrc, unsigned int count)
{
assert(strDes !=NULL && strSrc != NULL);
char *address = strDes;
while (count--&& *strSrc != '\0')
*strDes++ = *strSrc++;
*strDes = '\0';
return address;
}
//查找字符串s中首次出现字符c的位置
char *strchr(const char *str, int c)
{
assert(str !=NULL);
for (; *str != (char)c; ++ str)
if (*str == '\0')
return NULL;
return str;
}
int strcmp(const char *s, const char *t)
{
assert(s != NULL&& t != NULL);
while (*s&& *t && *s == *t)
{
++ s;
++ t;
}
return (*s -*t);
}
int strncmp(const char *s, constchar *t, unsigned int count)
{
assert((s != NULL) && (t !=NULL));
while (*s && *t && *s == *t&& count --)
{
++ s;
++ t;
}
return (*s - *t);
}
char *strcat(char *strDes, const char *strSrc)
{
assert((strDes != NULL) && (strSrc!= NULL));
char *address = strDes;
while (*strDes !='/0')
++ strDes;
while ((*strDes ++= *strSrc ++) != '/0')
NULL;
return address;
}
char *strncat(char *strDes, const char *strSrc,unsigned int count)
{
assert((strDes != NULL) && (strSrc!= NULL));
char *address = strDes;
while (*strDes !='/0')
++ strDes;
while (count --&& *strSrc != '/0' )
*strDes ++ =*strSrc ++;
*strDes = '/0';
return address;
}
int strlen(const char *str)
{
assert(str !=NULL);
int len = 0;
while (*str ++ != ‘\0’)
++ len;
return len;
}
//将字符串拷贝到新的位置
char *strdup_(char *strSrc)
{
if(strSrc!=NULL)
{
char *start=strSrc;
int len=0;
while(*strSrc++!='/0')
len++;
char *address=(char*)malloc(len+1);
assert(address!= NULL);
while((*address++=*start++)!='/0');
return address-(len+1);
}
return NULL;
}
char *strstr(const char *strSrc, const char *str)
{
assert(strSrc !=NULL && str != NULL);
const char *s = strSrc;
const char *t = str;
for (; *strSrc != '\0';++ strSrc)
{
for (s = strSrc,t = str; *t != '\0' && *s ==*t; ++s, ++t)
NULL;
if (*t == '\0')
return (char *) strSrc;
}
return NULL;
}
/* 功能:依次检验字符串s1中的字符,当被检验字符在字符串s2中也包含时,则停止检验,并返回该字符位置,空字符NULL不包括在内。*/
char *strpbrk(const char *strSrc, const char*str)
{
assert((strSrc !=NULL) && (str != NULL));
const char *s;
while (*strSrc != '\0')
{
s = str;
while (*s != '\0')
{
if (*strSrc == *s)
return (char *) strSrc;
++ s;
}
++ strSrc;
}
return NULL;
}
void *memcpy(void *dest, const void *src, unsigned int count)
{
assert((dest !=NULL) && (src != NULL));
void *address = dest;
while (count --)
{
*(char *) dest= *(char *) src;
dest = (char *)dest + 1;
src = (char *)src + 1;
}
return address;
}
5:总结
1:判断指针参数是否为NULL
2:如果参数只读不写,则需要添加const
3:函数中尽量不要调用其他库函数
4:申请内存后,需要判断是否申请成功
5:如果是内存函数,则注意指针类型
http://blog.csdn.net/v_JULY_v/article/details/6417600