3-3 编写expand(s1,s2)

编写expand(s1,s2),将字符串s1中类似于a-z类的速记符号在字符串s2中扩展为等价的完整列表abc.....xyz。该函数可以处理大小写字母和数字,并可以处理a-b-c,a-z0-9和-a-z等类似的情况。作为前导和尾随的-字符原样排印。
#include <stdio.h>
#include <string.h>
char *expand(char s1[], char s2[]);
int main()
{
    char str1[80];
    char str2[80];
    gets(str1);
    printf("%s\n", str1);
    printf("%s\n", expand(str1, str2));
    return 0;
}
1. 自己写的  好吧  实在太烂了。  
char *expand1(char s1[], char s2[])
{
    int i, j, c1, c2;
    i = 0;
    j = 0;
    if(s1[i] != '-')
        c1 = s1[i];
    else
    {
        s2[j++] = s1[i]; // 如果第一字符是‘-’,赋值给s2[j]
        ++i;
        c1 = s1[i];
    }
    while(s1[i++] != '\0')
    {
        if(i == 25 || i == 9) //考虑 这种情况 a-z0-9
        {
            while(c1 <= 'z') // 将a—z 存放到 s2[j]中 同时将 c1 赋值 0
            {
                s2[j++] = c1;
                ++c1;
            }
            ++i;
            c1 = s1[i];
        }
    }
    --i;
    c2 = s1[i];
    while(c1 <= c2)
        s2[j++] = c1++;
    s2[j] = '\0';
    return s2;
}
2. 主要是要判断 字符'- ' 和 
from The C Answer Book 只能处理a-z,-a-z,a-z0-9,a-b-c
/*expand: expand shortthand notation in s1 into string s2 */
char *expand(char s1[], char s2[])
{
    char c;
    int i, j;
    i = j = 0;
    while((c = s1[i++]) != '\0')   //把s1的一个字符放到变量 c中,再检查一下字符
        if(s1[i] == '-' && s1[i+1] >= c)  //如果下一个字符是-且再下一个字符大于或等于保存在变量c中的字符
        {
            i++;
            while(c < s1[i])  // 字符扩展
                s2[j++] = c++;
        }
        else
            s2[j++] = c;
    s2[j] = '\0';
    return s2;
}
3.  判断 字符' - ' :如果是第一个或最后一个,直接赋值。否则,利用函数strchr( )在定义的大写、小写、数字字母字符串中查找 字符‘-’前后的字符出现的
位置, 然后用指针 记录 速记符号在字符串中的地址,然后循环扩展。感觉这里处理的比较好,还考虑到字符是否是相同同类的,而且可以倒序输出,如”z-a“,
                p = start;
                while(p != end)
                {
                    s1[j++] = *p;
                    if(end > start)
                        ++p;
                    else
                        --p;
                }
;
如果速记符中第一个字符不是字符‘-’,而且它的下一个字符是字符‘-’而且不是‘\0’, 直接跳出字符‘-’,否则 , 就直接赋值给要扩展的字符串。
 
 #include <stdio.h>
#include <string.h>
void expand(char *s1, char *s2);
int main(void)
{
    char *s[] = { "a-z-", "z-a-", "-1-6-",
                  "a-ee-a", "a-R-L", "1-9-1",
                  "5-5", NULL
                };
    char result[100];
    int i = 0;
    while(s[i])
    {
        /* Expand and print the next string in our array s[] */
        expand(result, s[i]);
        printf("Unexpanded: %s\n", s[i]);
        printf("Expanded : %s\n", result);
        ++i;
    }
    return 0;
}
/* Copies string s2 to s1, expanding
ranges such as 'a-z' and '8-3' */
void expand(char *s1, char *s2)
{
    static char upper_alph[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    static char lower_alph[27] = "abcdefghijklmnopqrstuvwxyz";
    static char digits[11] = "0123456789";
    char *start, * end, * p;
    int i = 0;
    int j = 0;
    /* Loop through characters in s2 */
    while(s2[i])
    {
        switch(s2[i])
        {
        case '-':
            if(i == 0 || s2[i+1] == '\0')
            {
                /* '-' is leading or trailing, so just copy it */
                s1[j++] = '-';
                ++i;
                break;
            }
            else
            {
                /* We have a "range" to extrapolate. Test whether the two operands are part of the same range. If
                so, store pointers to the first and last characters
                in the range in start and end, respectively. If
                not, output and error message and skip this range. */
                if((start = strchr(upper_alph, s2[i-1])) &&
                        (end = strchr(upper_alph, s2[i+1])))   //dgh char *strchr(char* _Str,int _Ch) 功能:查找字符串s中首次出现字符c的位置   说明:返回首次出现c的位置的指针,如果s中不存在c则返回NULL。
                    ;
                else if((start = strchr(lower_alph, s2[i-1])) &&
                        (end = strchr(lower_alph, s2[i+1])))
                    ;
                else if((start = strchr(digits, s2[i-1])) &&
                        (end = strchr(digits, s2[i+1])))
                    ;
                else
                {
                    /* We have mismatched operands in the range,
                    such as 'a-R', or '3-X', so output an error
                    message, and just copy the range expression. */
                    fprintf(stderr, "EX3_3: Mismatched operands '%c-%c'\n",
                            s2[i-1], s2[i+1]);
                    s1[j++] = s2[i-1];
                    s1[j++] = s2[i++];
                    break;
                }
                /* Expand the range */
                p = start;
                while(p != end)
                {
                    s1[j++] = *p;
                    if(end > start)
                        ++p;
                    else
                        --p;
                }
                s1[j++] = *p;
                i += 2;
            }
            break;
        default:
            if(s2[i+1] == '-' && s2[i+2] != '\0')
            {
                /* This character is the first operand in
                a range, so just skip it - the range will
                be processed in the next iteration of
                the loop. */
                ++i;
            }
            else
            {
                /* Just a normal character, so copy it */
                s1[j++] = s2[i++];
            }
            break;
        }
    }
    s1[j] = s2[i]; /* Don't forget the null character */
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值