0%

3-3:expand(s1,s2)

文章时效性提示

本文发布于 467 天前,部分信息可能已经改变,请注意甄别。

《C程序设计语言》练习3-3
编写函数expand(s1,s2),将字符串s1中类似于a-z一类的速记符号在字符串s2扩展为等价的完整列表abc…xyz。该函数可以处理大小写字母和数字,并且可以处理a-b-c、a-z0-9与-a-z等类似的情况。作为前导和尾随的-字符原样排印。

处理a-z这种只有中间带有一个’-‘号这种最简单的情况:

思路:

  1. 先定位到’-‘号
  2. 分别找到符号左边和右边的字符
  3. 利用大小写字母和数字在ASCII码表中是有顺序这一特点,设置一个循环。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
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。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
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这种情况

思路:

  1. 对于这种情况,需要忽略最前面的’-‘号
  2. 加入判断’-‘位置的功能

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
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++;
                }
            }
        }
    }
}