当前位置:   article > 正文

机试:字符串相关简单问题

机试:字符串相关简单问题

字符移动问题

这道题的描述是这样的:输入一个字符串,将其中的数字字符移动到非数字字符之后,并保持数字字符和非数字字符输入时的顺序。例如:输入字符串“ab4f35gr#a6”,输出为“abfgr#a4356”。

以下使我试着敲的代码,思路很简单,遍历两遍字符串,第一遍把非数字的排好,第二遍再把数字排好。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. int main() {
  5. char str[100];
  6. char temp[100];
  7. gets(str);
  8. int len=strlen(str);
  9. int i=0,q=0;
  10. while(q<len){
  11. if(str[q]>'9'&&str[q]<'0'){
  12. temp[i++]=str[q];
  13. }
  14. q++;
  15. }
  16. q=0;
  17. while(q<len){
  18. if(str[q]<='9'&&str[q]>='0')temp[i++]=str[q];
  19. q++;
  20. }
  21. puts(temp);
  22. return 0;
  23. }

但是这段代码运行结果并不令我满意:

 

查询发现我犯了一个严重错误:

字符范围判断错误:条件str[q] > '9' && str[q] < '0'是逻辑上不可能的,因为在ASCII码中,'0'到'9'之间没有其他字符,因此这个条件永远不会为真。这意味着第一个while循环实际上不会把任何字符放进temp

因此作出修改:

 

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. int main() {
  5. char str[100];
  6. char temp[100];
  7. gets(str);
  8. int len=strlen(str);
  9. int i=0,q=0;
  10. while(q<len){
  11. if(str[q]>'9'||str[q]<'0'){
  12. temp[i++]=str[q];
  13. }
  14. q++;
  15. }
  16. q=0;
  17. while(q<len){
  18. if(str[q]<='9'&&str[q]>='0')temp[i++]=str[q];
  19. q++;
  20. }
  21. for(i=0;i<len;i++){
  22. printf("%c",temp[i]);
  23. }
  24. printf("\n");
  25. return 0;
  26. }

这样就可以了。同时做出的更改还有将输出字符串从puts()函数改成了printf()函数,原因是就算结果是正确的,我所输出的结果后还跟着一长串‘烫’字,不知道什么原因。。。

查询得到有可能是因为:

初始化与结尾处理:由于字符数组temp没有被明确地终止,因此在输出时可能包含未初始化的字符,导致出现乱码。

尝试改回去,在temp数组末尾加‘\0’。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. int main() {
  5. char str[100];
  6. char temp[100];
  7. gets(str);
  8. int len=strlen(str);
  9. int i=0,q=0;
  10. while(q<len){
  11. if(str[q]>'9'||str[q]<'0'){
  12. temp[i++]=str[q];
  13. }
  14. q++;
  15. }
  16. q=0;
  17. while(q<len){
  18. if(str[q]<='9'&&str[q]>='0')temp[i++]=str[q];
  19. q++;
  20. }
  21. temp[i]='\0';
  22. puts(temp);
  23. return 0;
  24. }

这样也是正确的。

字母统计问题

题目描述:输入一行字符串,计算其中A-Z大写字母出现的次数

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. int main() {
  5. char str[100];
  6. int len;
  7. int i;
  8. char c;
  9. while(scanf("%s",str)!=EOF){
  10. len=strlen(str);
  11. int count[26]={0};
  12. for(i=0;i<len;i++){
  13. if(str[i]>='A'&&str[i]<='Z')count[str[i]-'A']++;
  14. }
  15. for(i=0,c='A';c<='Z';c++){
  16. printf("%c:%d\n",c,count[i++]);
  17. }
  18. }
  19. return 0;
  20. }

首字母大写问题

题目描述:对一个字符串中的所有单词,如果单词的首字母不是大写字母,则把单词的首字母变成大写字母。 在字符串中,单词之间通过空白符分隔,空白符包括:空格(' ')、制表符('\t')、回车符('\r')、换行符('\n')。

真的会被字符串的题的细节坑到。。。

上代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. int main() {
  5. char str[100];
  6. int len;
  7. int i;
  8. char c;
  9. while(scanf("%s",str)!=EOF){
  10. len=strlen(str);
  11. c=' ';
  12. for(i=0;i<len;i++){
  13. if(c==' '||c=='\t'||c=='\n'||c=='\r'){
  14. if(str[i]<='z'&&str[i]>='a'){
  15. str[i]=str[i]-'a'+'A';
  16. }
  17. }
  18. c=str[i];
  19. }
  20. puts(str);
  21. /*
  22. for(i=0;i<len;i++){
  23. printf("%c",str[i]);
  24. }
  25. printf("\n");
  26. */
  27. }
  28. return 0;
  29. }

给看一下这段代码的运行结果:

是的,它把每一个空格隔开的字符串当成完全独立的字符串了o(╥﹏╥)o

搜索得知:

在C语言中,使用fgets函数可以安全地读取带有空格的字符串,并且你可以指定一个最大的字符数来防止缓冲区溢出。此外,可以检查字符串中是否包含换行符来确定用户是否按下了回车键。

char *fgets(char *str, int n, FILE *stream);

fgets 是 C 语言中用于从指定的输入流读取字符串的函数。常用来读取标准输入 (stdin) 或从文件读取数据。

这里解释一下每个参数的含义:

  • str:指向一个字符数组的指针,这个数组用于存储从输入流读取的字符串。这个数组应该足够大,以存储读取到的字符串以及字符串终止符 \0

  • n:要读取的最大字符数(包括字符串终止符 \0)。fgets 最多会读取 n-1 个字符,并且会在末尾加上一个字符串终止符。这样做是为了确保读取的字符串是正确终止的。

  • stream:指定要读取的输入流。在读取标准输入时,这个参数是 stdin,也可以是指向文件流的指针,用于从文件读取数据。

在读取字符串后,fgets 会返回 str,如果遇到错误或到达文件末尾,则返回 NULL

完整可运行代码如下:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. int main() {
  5. char str[105];
  6. int len;
  7. int i;
  8. char c;
  9. while(fgets(str, sizeof(str), stdin) != NULL){
  10. len=strlen(str);
  11. str[--len]='\0';//清除掉末尾'\0'前的回车符'\r'
  12. c=' ';
  13. for(i=0;i<len;i++){
  14. if(c==' '||c=='\t'||c=='\n'||c=='\r'){
  15. if(str[i]<='z'&&str[i]>='a'){
  16. str[i]=str[i]-'a'+'A';
  17. }
  18. }
  19. c=str[i];
  20. }
  21. puts(str);
  22. }
  23. return 0;
  24. }

统计单词的问题

题目描述:编一个程序,读入用户输入的,以“.”结尾的一行文字,统计一共有多少个单词,并分别输出每个单词含有多少个字符。 (凡是以一个或多个空格隔开的部分就为一个单词)

不知道为什么,这段代码可以在牛客上运行成功,但在n诺上不行:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. int main() {
  5. char str[105];
  6. int len;
  7. int i, count;
  8. char c;
  9. while (fgets(str, sizeof(str), stdin) != NULL) {
  10. len = strlen(str);
  11. str[--len] = '\0'; //清除掉末尾'\0'前的回车符'\r'
  12. i = 0;
  13. c = ' ';
  14. while (i < len) {
  15. count = 0;
  16. c = str[i];
  17. while ((str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= 'a' && str[i] <= 'z')) {
  18. count++;
  19. c = str[i];
  20. i++;
  21. }
  22. if ((str[i] == ' ' || str[i] == '.') && c != ' ')printf("%d ", count);
  23. i++;
  24. }
  25. printf("\n");
  26. }
  27. return 0;
  28. }

又研究了一下,发现n诺上的代码测试中有的样例没有在句子后面加‘.’,因此这段代码才会出错,只需修改一行就行了:

if((str[i]==' '||str[i]=='.'||str[i]=='\0')&&c!=' ')printf("%d ",count);

删除字符串问题

题目描述:

给你一个字符串S,要求你将字符串中出现的所有"gzu"(不区分大小写)子串删除,输出删除之后的S。

就是说出现“Gzu”、“GZU”、“GZu”、"gzU"都可以删除。

代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. int main() {
  5. char str[105];
  6. char temp[105];
  7. int len;
  8. int i,count;
  9. char c;
  10. while(fgets(str, sizeof(str), stdin) != NULL){
  11. len=strlen(str);
  12. count=0;
  13. str[--len]='\0';//清除掉末尾'\0'前的回车符'\r'
  14. for(i=0;i<len;){
  15. if((str[i]=='g'||str[i]=='G')&&(str[i+1]=='z'||str[i+1]=='Z')&&(str[i+2]=='u'||str[i+2]=='U')){
  16. i+=3;
  17. continue;
  18. }
  19. temp[count++]=str[i++];
  20. }
  21. temp[count]='\0';
  22. puts(temp);
  23. }
  24. return 0;
  25. }

这里的字符串问题都比较简单,没有牵扯较难的算法。在机试当中,很多时候都会考到字符串相关的问题,尤其是查找和删除。之后我会学习解决更多关于字符串的问题。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/572680
推荐阅读
相关标签
  

闽ICP备14008679号