《C程序设计语言》练习3-3
编写函数expand(s1,s2),将字符串s1中类似于a-z一类的速记符号在字符串s2扩展为等价的完整列表abc…xyz。该函数可以处理大小写字母和数字,并且可以处理a-b-c、a-z0-9与-a-z等类似的情况。作为前导和尾随的-字符原样排印。
处理a-z这种只有中间带有一个’-‘号这种最简单的情况:
思路:
- 先定位到’-‘号
- 分别找到符号左边和右边的字符
- 利用大小写字母和数字在ASCII码表中是有顺序这一特点,设置一个循环。
代码:
123456789101112131415161718192021222324252627 | void expand(char s1[],char s2[]);int main(){ char s1[] = "A-Z"; char s2[100] = {0}; expand(s1, s2); return 0;}void expand(char s1[],char s2[]){ int Locate = 0;//'-'号的位置 for (Locate=0; s1[Locate] != '\0'; Locate++) { if (s1[Locate] == '-')//找到了'-'号 { char Left = s1[Locate-1];//减号左边的字符 char Right = s1[Locate+1];//减号右边的字符 for (int i = 0; Right - Left >= 0; i++) { //让s2[i]这个字符一直等于Left,知道Right和Left相等。 s2[i] = Left; Left = Left + 1; } } }} |
处理a-b-c 这种带有多个’-‘号的情况
思路:在之前代码的前提下,即使最内层的for循环结束,也要记录i的值,便于下次再找到’-‘时接着上次的位置赋值给s2。
代码:
12345678910111213141516171819202122232425262728293031323334353637 | void expand(char s1[],char s2[]);int main(){ char s1[] = "A-D-G-K"; char s2[100] = {0}; expand(s1, s2); return 0;}void expand(char s1[],char s2[]){ int Locate = 0;//'-'号的位置 for (Locate=0; s1[Locate] != '\0'; Locate++) { if (s1[Locate] == '-')//找到了'-'号 { int i = 0; static int j = 0;//记录s2字符串已经被写入的位置 char Left = s1[Locate-1]; char Right = s1[Locate+1]; for (i = j; Right - Left >= 0; ) { if (s2[i-1] == Left)//如果是相等的,就跳过这次对s2的写入 { Left = Left + 1; } else { s2[i] = Left; Left = Left + 1; j++; i++; } } } }} |
经过测试,这段代码也解决了a-z0-9的问题。
处理-a-z这种情况
思路:
- 对于这种情况,需要忽略最前面的’-‘号
- 加入判断’-‘位置的功能
代码:
12345678910111213141516171819202122232425262728293031323334353637 | void expand(char s1[],char s2[]);int main(){ char s1[] = "-a-z"; char s2[100] = {0}; expand(s1, s2); return 0;}void expand(char s1[],char s2[]){ int Locate = 0;//'-'号的位置 for (Locate=0; s1[Locate] != '\0'; Locate++) { if (s1[Locate] == '-' && Locate != 0)//找到了'-'号,并且这个'-'号不在数组最前面。 { int i = 0; static int j = 0; char Left = s1[Locate-1]; char Right = s1[Locate+1]; for (i = j; Right - Left >= 0; ) { if (s2[i-1] == Left) { Left = Left + 1; } else { s2[i] = Left; Left = Left + 1; j++; i++; } } } }} |