【发布时间】:2021-10-15 14:10:06
【问题描述】:
我已经解决了 K&R 书中的练习 3.3。我实施的解决方案似乎有效,但有点冗长,可能有更聪明的方法来编写这段代码。我想问一下我实现的解决方案是否存在问题,以及是否有更简单的方法来编写它:
编写一个扩展速记符号的函数 expand(s1,s2),例如 将字符串 s1 中的 a-z 放入等效的完整列表 abc...xyz 中 s2。允许使用大小写和数字的字母,并准备好 处理像 a-b-c 和 a-z0-9 和 -a-z 这样的情况。安排一个领先的或 尾随 - 字面意思
我的代码是这个:
#include <stdio.h>
void expand(char s1[],char s2[]){
int j=0,i=0;
while(s1[j] != '\0'){
if (s1[j]>= 'a' && s1[j] <= 'z' && s1[j+1] == '-' && s1[j+1]!='\0' && s1[j+2] >= 'a' && s1[j+2] <= 'z' && s1[j+2] !='\0'){
int z = s1[j+2]-s1[j];
int c;
for (c=0;c<=z;c++){
s2[i]= c+s1[j];
i++;
}
j=j+3;
}
else if (s1[j]>= 'A' && s1[j] <= 'Z' && s1[j+1] == '-' && s1[j+1]!='\0' && s1[j+2] >= 'A' && s1[j+2] <= 'Z' && s1[j+2] !='\0'){
int z = s1[j+2]-s1[j];
int c;
for (c=0;c<=z;c++){
s2[i]= c+s1[j];
i++;
}
j=j+3;
}
else if (s1[j]>= '0' && s1[j] <= '9' && s1[j+1] == '-' && s1[j+1]!='\0' && s1[j+2] >= '0' && s1[j+2] <= '9' && s1[j+2] !='\0'){
int z = s1[j+2]-s1[j];
int c;
for (c=0;c<=z;c++){
s2[i]= c+s1[j];
i++;
}
j=j+3;
}
else if (j!= 0 && s1[j] == '-' && (s1[j-1] < s1[j+1])){
int z = s1[j+1]-(1+s1[j-1]);
int c;
for (c=0;c<=z;c++){
s2[i]= c+(s1[j-1]+1);
i++;
}
j=j+2;
}
else if ( s1[j]>= 32 && s1[j] <= 127 && (s1[j+1] != '-' || s1[j+1]>= 32 && s1[j+1] <= 127 )){
s2[i] = s1[j];
j++;
i++;
}
}
s2[i]='\n';
i++;
s2[i]='\0';
}
int main() {
int c;
char s2[100];
expand("-a-c,a-c-g,A-Z0-9--", s2);
printf("%s",s2);
}
代码是这样工作的:
首先它检查是否存在 x 条件 else if (j!= 0 && s1[j] == '-' && (s1[j-1] < s1[j+1])) 用于检查“a-c-d1”等情况。我在这个例子中实现的代码将像这样工作:
由于我们从“a-c-d”中的第 0 个字符开始并且存在模式“x-y”,因此“abc”将被分配给数组。那我们就直接跳到第二个——在“a-c-f”。由于第二个 - 前面有一个字母“c”,后面是一个字母“f”,并且“c”
【问题讨论】:
-
表达式
s1[j+1] == '-' && s1[j+1]!='\0'是多余的。如果它等于-,那么它肯定不等于其他任何东西。s1[j+2]相同 - 如果它介于'A'和'Z'之间,则不能是'\0' -
这个问题可能更适合CodeReview 网站。
-
这个问题的代码很多,代码重复也很多。我个人会这样做:godbolt.org/z/WM45dGvs1
-
结果有问题吗?
-
@PtitXav 我在其他测试中没有遇到问题,但想问问是否有更简单的方法来回答这个练习。