今天集训的内容是字符串中的字符串遍历题,仍然是简单题,但也可以掌握一些字符串所必要的知识,加深对字符串的理解,关于字符数组和字符串,字符串的输入输出在这就不再做过多赘述,关于字符串的问题,我们一般需要先用系统库函数malloc开辟一块空间用来存放字符串,并返回指向这段空间首地址的指针,下面看看都有哪些题型:
1.URL化
char* replaceSpaces(char* S, int length){char* str=(char*)malloc(sizeof(char)*length*30);int size=0;for(int i=0;i<length;i++){if(S[i]==' '){str[size++]='%';str[size++]='2';str[size++]='0';}else{str[size++]=S[i];}}str[size]='\0';return str;
}
这道题大体思路就是遍历整个字符串,找到空格并替换,然后返回字符串,首先我们需要开辟一块空间,然后返回指向空间首地址的指针,相当于开辟了新的一块空间来存放修改后的字符串,接下来进行遍历,没遇到空格时就在对应下标处进行赋值,遇到空格时就把把空格替换成%20,要注意的是i的取值最大只能到字符串的真实长度length,还有就是字符串的末尾需要加"\0"来进行结束,否则会报错。
2.长度为三且各字符不同的子字符串
int countGoodSubstrings(char* s) {int cnt=0;int len=strlen(s);for(int i=0;i<len-2;i++){if(s[i]!=s[i+1]&&s[i]!=s[i+2]&&s[i+1]!=s[i+2])cnt++;}return cnt;
}
这道题也是比较简单的,就是从头到尾遍历,注意每次比较的元素个数为3,为了不造成数组访问越界,i<len-2,如果各不相同,计数器cnt加1,最后返回即可。
3.将所有数字用字符替换
char* replaceDigits(char* s) {for(int i=0;s[i];i++){if(i%2!=0)s[i]=s[i-1]+s[i]-'0';}return s;
}
这道题也没什么可说的,只需要处理奇数位下标即可,遇到数字时,就把它替换成它前一位的字符加上该位的数字所得到的字符,唯一值得注意的是,这里需要减'0',因为s[i]是字符1,而不是数字1,所以我们要减去'0'才能得到数字1,如果不这样做,加上的将是字符1的ASCII码值1,答案错误。
4.动态口令
char* dynamicPassword(char* password, int target) {int len=strlen(password);char* str=(char*)malloc(sizeof(char)*len+1);int size=0;for(int i=target;i<len;i++){str[size++]=password[i];}for(int i=0;i<target;i++){str[size++]=password[i];}str[size]='\0';return str;
}
这道题在申请空间时为什么要加1,因为需要给'\0'留空间,像这种需要对字符串进行修改的,一般都要开辟空间来存储新的字符串,这道题也不例外,分两段进行存放,第一段是target之后的字符串,第二段是target之前的字符串,最后加上'\0'返回即可。
5.字符串轮转
bool isFlipedString(char* s1, char* s2){int len1=strlen(s1);int len2=strlen(s2);if(len1!=len2)return false;char* str=(char*)malloc(sizeof(char)*len1*2+1);int i=0;for(i=0;i<2*len1;i++){str[i]=s1[i%len1];}str[i]='\0';if(strstr(str,s2)!=NULL)return true;return false;
}
这道题很有意思,首先就要比较两个字符串的长度,如果长度都不一样,那肯定不符合要求了,长度相同的情况下,我们怎么才能知道s2是不是s1轮转而成呢?其实你会发现,如果s2是由s1轮转而成,那必然会和s1+s1中的某一个子串匹配,基于这个想法,我们先获取s1+s1,然后调用strstr库函数查找s2是否在str中出现,如果出现会返回第一次出现的字符串的首地址,如果没有,会返回空指针。这个题在后面其实就是KMP算法的基本应用,感兴趣的可以提前了解一下。
今天题都比较简单,主要是申请多少空间,循环的终止条件可能会出错,造成数组的越界访问,其他也没什么问题,感谢大家的阅读!