C语言K&R习题3-3 expand,编写函数expand(s1, s2),将字符串s1中类似于a-z一类的速记符号在字符串s2中扩展为等价的完整列表abc...xyz。

文章介绍了一个C语言函数,该函数能处理包含速记符号(如a-z)的字符串,将其扩展为完整的字符序列。函数可以处理大小写字母和数字,以及前导和尾随的破折号。代码示例展示了不同输入的处理结果,并对比了书中的参考答案,指出了其局限性。
摘要由CSDN通过智能技术生成

 编程思路

该函数可以处理大小写字母和数字,并可以处理a-b-c、a-z0-9 与 -a-z等类似的情况。作为前导和尾随的-字符原样排印。

思路很明确,检测字符’-‘,如果字符’-‘前后均为字母,说明这段为速记,判断前后字母的大小关系,字母是否相等,根据不同情况进行s2数据的输入。未检测到字符’-‘时,将s1元素原样复制到s2的最后一位。

!要注意,s2内的字符串长度与s1是不一样的,可以定义一个变量记录s2待输入的元素序号,亦可以灵活运用string.h内的strlen语句,读取s2的末尾标号。

用于程序编写时使用了strlen(),数组s2输入expand前要进行初始化,char s2 = {};

#include<stdio.h>
#include<string.h>
#define MAXLEN 100
// 编写函数expand(s1, s2),将字符串s1中类似于a-z一类的速记符号在字符串s2中扩展为等价的完整列表abc...xyz。
//该函数可以处理大小写字母和数字,并可以处理a-b-c、a-z0-9 与 -a-z等类似的情况。作为前导和尾随的-字符原样排印。
void expand(char s1[],char s2[])
{
    int i,j,k;
    for(i=0;i<strlen(s1);++i)
    {
        if(s1[i]=='-')
        {
            if(i!=0 && s1[i-1]!='-' && s1[i+1]!='-')
            {
                if(s1[i-1] < s1[i+1])
                {
                    j=strlen(s2);
                    s2[j++]=s1[i-1]+1;
                    for(k=1;k<(s1[i+1]-s1[i-1]-1);k++)
                    {
                        s2[j]=s2[j-1]+1;
                        j++;
                    }
                }
                else if(s1[i-1] > s1[i+1])
                {
                    j=strlen(s2);
                    s2[j++]=s1[i-1]-1;
                    for(k=1;k<(s1[i-1]-s1[i+1]-1);k++)
                    {
                        s2[j]=s2[j-1]-1;
                        j++;
                    }
                }
                else
                {
                    s2[strlen(s2)]=s1[i];
                }
            }
            else
                {
                    s2[strlen(s2)]=s1[i];
                }
        }
        else
        {
            s2[strlen(s2)]=s1[i];
        }
    }
}

main()
{
    char s1[MAXLEN]={},s2[MAXLEN]={};
    int i=0,c;
    while((c=getchar())!='\n')
    {
        s1[i++] = c;
    }
    s1[i]='\0';
    expand(s1,s2);
    printf("s1 is %s\ns2 is %s",s1,s2);
}

输出示例:

TEST1:

-a-z--a-c
s1 is -a-z--a-c
s2 is -abcdefghijklmnopqrstuvwxyz--abc

TEST2:

-a-c-c-a
s1 is -a-c-c-a
s2 is -abc-cba

 TEST3:(’F‘ ascii = 65;’a‘ ascii =97)

--A-F-aa-z--0-5--TEST3
s1 is --A-F-aa-z--0-5--TEST3
s2 is --ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`aabcdefghijklmnopqrstuvwxyz--012345--TEST3

书中的参考答案 

/* expand: expand shorthand notation in s1 into string s2   */
void expand(char s1[], char s2[])
{
    char c;
    int i, j;
    
    i = j = 0;
    while((c = s1[i++]) != '\0')    /* fetch a char from s1[]   */
        if(s1[i] == '-' && s1[i + 1] >= c)
        {
            i++;
            while(c < s1[i])        /* expand shorthand         */
                s2[j++] = c++;
        }
        else
            s2[j++] = c;            /* copy the character       */
    s2[j] = '\0';
}

未实现对如 c-a 等输入的扩展,同时无法处理连续’-‘,如-a--c-a,运行结果如下:

本文代码运行结果

-a--c-a
s1 is -a--c-a
s2 is -a--cba

 答案代码运行结果

 

-a--c-a
s1 is -a--c-a
s2 is -a-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc-a

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值