注:leetcode上的此题需要另辟空间,不是像剑指书上那样是原地修改,所以字符串从第一个或最后一个字符移动对时间复杂度没有影响,有点脱离此题的本意。
char* replaceSpace(char* s){
if (s == NULL)
return NULL;
int blank_num = 0, len = 0;
char *ptr = s;
while (*ptr != '\0') {
if (*ptr == ' ')
blank_num++;
len++;
ptr++;
}
int new_len = len + blank_num*2; //有效长度,不计'\0'
char *new_s = (char*)malloc((new_len+1) * sizeof(char));
int i = 0, j = 0;
while (i < len) { //有效字符的移动或转换
if (s[i] == ' ') {
new_s[j++] = '%';
new_s[j++] = '2';
new_s[j++] = '0';
} else {
new_s[j++] = s[i];
}
i++;
}
new_s[new_len] = '\0'; //容易遗漏或写成new_s[new_len-1]
return new_s;
}
查看题解,发现大家有几点处理略有不同,拿出来学习学习:
1:用strlen(s)求出len,然后分配3*len+1的空间。
涉及知识点:unsigned int strlen(char *s):计算给定字符串的(unsigned int型)长度,不包括'\0'在内
//能想到用现有库函数固然很好,但是不精细,当字符串较大空格较少时尤其浪费空间
2:使用strncat(new_s, s+i, 1)和strcat(new_s, "%20"),用追加字符或字符串来代替复制操作,不用追加字符串最后的'\0',也不用维护new_str的下标。
涉及知识点:
char *strcat(char *dest, const char *src):把src所指向的字符串(包括'\0')复制到dest所指向的字符串后面(覆盖*dest原来末尾的'\0')。
char * strncat(char *dest, const char *src, size_t n):把src所指字符串的前n个字符追加到dest所指字符串的结尾处(覆盖*dest原来末尾的'\0'),再追加'\0'。
两个函数都返回指向dest的指针,并且都需要保证src和dest所指内存区域不可以重叠,并且dest必须有足够的空间来容纳src的字符串。
//扩展了知识面,知而善用,可谓熟练
3:用(char*)calloc(new_len+1,sizeof(char))分配空间,不用追加字符串最后的'\0'。
涉及知识点:void* calloc(unsigned int num,unsigned int size):相较于malloc函数,calloc函数自动会将所分配的内存空间中的每一位都初始化为零。
也就意味着如果是数值型就是对应类型的0值,如果是指针或者字符,就是空指针或'\0'('\0'的ascii 码是0)
//关于内存分配的相关函数,有时间需整理发布。