c0505_扩展字符串(a-d-g扩展为abcdefg)
【问题描述】
编写一函数expand(s1,s2),用以将字符串s1中的缩记符号在字符串s2中扩展为等价的完整字符,例如将a-d扩展为abcd。该函数可以处理大小写字母和数字,并可以处理a-b-c、a-z0-9与-az等类似的情况。在main函数中测试该函数:从键盘输入包含缩记符号的字符串,然后调用该函数进行扩展,输出扩展结果。(教材 P63:Exercise 3-3)
注意:
待扩展字符串中有可能包含空格,例如:a-d x-z应扩展成:abcd xyz。所以读入待扩展字符串时,应能够读入包含空格的字符串;
只要缩记符号-之后的字符比之前的字符的ASCII码值大,就要将它们之间的所有字符扩展出来,例如:Z-a之间的字符也要扩展出来;
特殊情况:a-b-c将被扩展为:abc。a-a将被扩展为:a-a。
【输入形式】 从键盘输入包含扩展符的字符串
【输出形式】 输出扩展后的字符串
【输入样例】 a-c-u-B
【输出样例】 abcdefghijklmnopqrstu-B
------------------------------
个人代码:
#include <stdio.h> #include <string.h> int expand(char *s1, char *s2){ int l,i,j; char k; l = strlen(s1); for(i=0,j=0;i<l;i++,j++){ if(s1[i]=='-'){ if(i==0 || i==l-1) s2[j] = '-'; else if(s1[i-1]<s1[i+1]){ for(k=s1[i-1]+1;k<s1[i+1];k++,j++) s2[j] = k; j--; } else{ s2[j] = '-'; } } else{ s2[j] = s1[i]; } } s2[j] = '\0'; return 0; } int main(){ char s1[256],s2[256]; gets(s1); expand(s1,s2); puts(s2); getchar(); return 0; }
标答:
#include <stdio.h> #include <ctype.h> void expand(char *s1, char *s2); main() { char s1[1024], s2[1024]; int i = 0, c; while ((c = getchar()) != EOF) { s1[i++] = c; } expand(s1, s2); printf("%s\n", s2); } void expand(char *s1, char *s2) { int i = 0, j = 0, k; while (1) { if (s1[i] == '-') { s2[j++] = '-'; i++; } else break; } while (s1[i] != '\0') { if (s1[i] == ' ') { s2[j++] = ' '; i++; while (1) { if (s1[i] == '-') { s2[j++] = '-'; i++; } else break; } continue; } if (s1[i] == '-' && s1[i+1] > s1[i-1]) { if (s1[i-2] == '-' && s1[i-3] != '-' &&s1[i-3] != ' ' && i>=3) { j -= 1; k = 0; while (s2[j-1] != s1[i+1]) { s2[j] = s1[i-1] + k; j++; k++; } } else { k = 0; while (s2[j-1] != s1[i+1]) { s2[j] = s1[i-1] + k; j++; k++; } } } else if (s1[i] == '-' && s1[i+1] < s1[i-1] && s1[i-2] != '-') { s2[j++] = s1[i-1]; s2[j++] = s1[i]; s2[j++] = s1[i+1]; } else if (s1[i] == '-' && s1[i+1] < s1[i-1] && s1[i-2] == '-') { s2[j++] = s1[i]; s2[j++] = s1[i+1]; } else if (s1[i] != '-' && s1[i+1] != '-' && s1[i-1] != '-') { s2[j++] = s1[i]; s2[j] = s1[i+1]; } i++; } s2[j] = '\0'; }
------------------------------
1、读取字符串的三种方式:
1)scanf("%s")方式
char s[256]; scanf("%s", s);
(注意:scanf("%s", s);中的"s"前不用加地址符&,因为s[]为数组。)
遇TAB、Space、回车则读取结束,因此该方式不能读取带有空格的字符串。
读取结束后会在字符串尾自动添加'\0'作为结束符。
2)getchar()(或者scanf("%c"))方式
char s[1024]; int i = 0, c; while ((c = getchar()) != EOF) { s[i++] = c; } s[i] = '\0';
(注意:while条件中的 “c = getchar()” 语句里的变量 c 必须为 int 型,不能为 char 型,因为 char 型不包含负值,而EOF在函数库里一般定义为-1,为了能获取到所有可能的值,需将变量 c 定义为可正可负的 int 型。)
EOF (Enf Of File)在Windows环境下为“回车后Ctrl+Z”。
读取结束的条件可自定,若while ((c = getchar()) != '\n') {...;}则表示遇回车则读取结束。因此该方式可以读取带回车、Space等其他特殊字符的字符串。
读取结束后不会自动添加'\0'结束符,因此需手动用s[i] = '\0';加结束符。
3)gets()方式(不需要额外的头文件)
char s[256]; gets(s);
遇回车则读取结束,因此该方式可以读取带Space的字符串。
读取结束时会把'\n'读取,转换为'\0',输入流中不再有'\n',因此该方式会自动添加'\0'结束符。
2、输出字符串的方式:(以下两种方法效果相同)
1)puts()方式
char s[1024]; puts(s1);
以'\0'为输出截止符。
2)printf("%s")方式
char s[1024]; printf("%s\n", s);
以'\0'为输出截止符。