第一节、字符串查找
1.1题目描述:
给定一个字符串A,要求在A中查找一个子串B。
如A="ABCDF",要你在A中查找子串B=“CD”。
分析:比较简单,相当于实现strstr库函数
//在字符串中查找指定字符串的第一次出现,不能找到则返回-1
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;
int i,j;
for (i = 0; i <= len; i++) //复杂度为O(m*n)
{
for (j = 0; j < lensub; j++)
{
if (string[i+j] != substring[j])
break;
}
if (j == lensub)
return i + 1;
}
return -1;
}
1.2、题目描述
在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。
char FirstNotRepeatChar(char* pString)
{
if(!pString)
return '\0';
const int tableSize = 256;
//有点要提醒各位注意,一般常数的空间消耗,如这里的256,我们也认为此空间复杂度为O(1)。
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'; //没有找到满足条件的字符,退出
}
位图法
const int N = 26;
int bit_map[N];
void findNoRepeat(char *src)
{
int pos;
char *str = src;
int i ,len = strlen(src);
//统计
for(i = 0 ; i < len ;i ++)
bit_map[str[i]-'a'] ++;
//从字符串开始遍历 其bit_map==1 那么就是结果
for(i = 0 ; i < len ; i ++)
{
if(bit_map[str[i]-'a'] == 1)
{
printf("%c",str[i]);
return ;
}
}
}
第二节、字符串拷贝
题目描述:
要求实现库函数strcpy,
原型声明:extern char *strcpy(char *dest,char *src);
功能:把src所指由NULL结束的字符串复制到dest所指的数组中。
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针。
char * strcpy( char *strDest, const char *strSrc )
{
if(strDest == strSrc) { return strDest; }
assert( (strDest != NULL) && (strSrc != NULL) );
char *address = strDest;
while( (*strDest++ = * strSrc++) != '\0' );
return address;
}
第三节、小部分库函数的实现
1
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;
}
2
//查找字符串s中首次出现字符c的位置
char *strchr(const char *str, int c)
{
assert(str != NULL);
for (; *str != (char)c; ++ str)
if (*str == '\0')
return NULL;
return str;
}
3
int strcmp(const char *s, const char *t)
{
assert(s != NULL && t != NULL);
while (*s && *t && *s == *t)
{
++ s;
++ t;
}
return (*s - *t);
}
4
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;
}
5
int strlen(const char *str)
{
assert(str != NULL);
int len = 0;
while (*str ++ != '\0')
++ len;
return len;
}
6
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;
}
7
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;
}
8
int strncmp(const char *s, const char *t, unsigned int count)
{
assert((s != NULL) && (t != NULL));
while (*s && *t && *s == *t && count --)
{
++ s;
++ t;
}
return (*s - *t);
}
9
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;
}
10
int strcspn(const char *strSrc, const char *str)
{
assert((strSrc != NULL) && (str != NULL));
const char *s;
const char *t = strSrc;
while (*t != '\0')
{
s = str;
while (*s != '\0')
{
if (*t == *s)
return t - strSrc;
++ s;
}
++ t;
}
return 0;
}
11
char *strrchr(const char *str, int c)
{
assert(str != NULL);
const char *s = str;
while (*s != '\0')
++ s;
for (-- s; *s != (char) c; -- s)
if (s == str)
return NULL;
return (char *) s;
}
char* strrev(char *str)
{
assert(str != NULL);
char *s = str, *t = str, c;
while (*t != '\0')
++ t;
for (-- t; s < t; ++ s, -- t)
{
c = *s;
*s = *t;
*t = c;
}
return str;
}
char *strnset(char *str, int c, unsigned int count)
{
assert(str != NULL);
char *s = str;
for (; *s != '\0' && s - str < count; ++ s)
*s = (char) c;
return str;
}
char *strset(char *str, int c)
{
assert(str != NULL);
char *s = str;
for (; *s != '\0'; ++ s)
*s = (char) c;
return str;
}
12
char *strtok(char *strToken, const char *str)
{
assert(str != NULL);
static char *last;
if (strToken == NULL && (strToken = last) == NULL)
return (NULL);
char *s = strToken;
const char *t = str;
while (*s != '\0')
{
t = str;
while (*t != '\0')
{
if (*s == *t)
{
last = s + 1;
if (s - strToken == 0) {
strToken = last;
break;
}
*(strToken + (s - strToken)) = '\0';
return strToken;
}
++ t;
}
++ s;
}
return NULL;
}
char *strupr(char *str)
{
assert(str != NULL);
char *s = str;
while (*s != '\0')
{
if (*s >= 'a' && *s <= 'z')
*s -= 0x20;
s ++;
}
return str;
}
char *strlwr(char *str)
{
assert(str != NULL);
char *s = str;
while (*s != '\0')
{
if (*s >= 'A' && *s <= 'Z')
*s += 0x20;
s ++;
}
return str;
}
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;
}
void *memccpy(void *dest, const void *src, int c, unsigned int count)
{
assert((dest != NULL) && (src != NULL));
while (count --)
{
*(char *) dest = *(char *) src;
if (* (char *) src == (char) c)
return ((char *)dest + 1);
dest = (char *) dest + 1;
src = (char *) src + 1;
}
return NULL;
}
void *memchr(const void *buf, int c, unsigned int count)
{
assert(buf != NULL);
while (count --)
{
if (*(char *) buf == c)
return (void *) buf;
buf = (char *) buf + 1;
}
return NULL;
}
int memcmp(const void *s, const void *t, unsigned int count)
{
assert((s != NULL) && (t != NULL));
while (*(char *) s && *(char *) t && *(char *) s == *(char *) t && count --)
{
s = (char *) s + 1;
t = (char *) t + 1;
}
return (*(char *) s - *(char *) t);
}
//@big:
//要处理src和dest有重叠的情况,不是从尾巴开始移动就没问题了。
//一种情况是dest小于src有重叠,这个时候要从头开始移动,
//另一种是dest大于src有重叠,这个时候要从尾开始移动。
void *memmove(void *dest, const void *src, unsigned int count)
{
assert(dest != NULL && src != NULL);
char* pdest = (char*) dest;
char* psrc = (char*) src;
//pdest在psrc后面,且两者距离小于count时,从尾部开始移动. 其他情况从头部开始移动
if (pdest > psrc && pdest - psrc < count)
{
while (count--)
{
*(pdest + count) = *(psrc + count);
}
} else
{
while (count--)
{
*pdest++ = *psrc++;
}
}
return dest;
}
void *memset(void *str, int c, unsigned int count)
{
assert(str != NULL);
void *s = str;
while (count --)
{
*(char *) s = (char) c;
s = (char *) s + 1;
}
return str;
}