TCPL——练习3.3
TCPL练习3-3的题目是这样的:函数expand(s1, s2),将字符串中s1中类似a-z的速记扩展为:abcd...xyz,并能处理大小写,并可以处理a-b-c-d, a-z0-9, -a-z这样的情况,前导的-字符照样排印。
我记得这道题在豆瓣上看朋友用PY写得很简洁,用C写的代码看起来比较累赘,可能也是我想得比较复杂。代码:
代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 100
#define MINSIZE 50
static int is_iterable(int c)
{
if (islower(c) || isupper(c) || isdigit(c) ) {
return 1;
}
return 0;
}
int expand(const char *s1, char *s2)
{
int i, j;
int b, e;
int count = 0;
int s2_len = 0;
for (i = 0; s1[i] == '-'; ++i) {
s2[s2_len++] = '-';
}
for ( ; s1[i] != '\0'; ++i) {
if (is_iterable(s1[i]) ) {
if (s1[i+1] == '-') {
b = s1[i];
e = s1[i + 2];
for (j = 0, count = e - b + 1; j < count; ++b, ++j) {
if (s2[s2_len-1] != b) {
s2[s2_len++] = b;
}
}
} else {
s2[s2_len++] = s1[i];
}
} else {
s2[s2_len++] = s1[i];
}
i += s1[i+3] == '-' ? 1 : 2;
}
return s2_len;
}
int main(void)
{
int len;
char s1[MINSIZE] = {0};
char s2[MAXSIZE] = {0};
while (1) {
printf("input string(a-z,0-9,.., 'quit' to exit):\n");
memset(s1, 0x00, sizeof(s1));
fgets(s1, MINSIZE, stdin);
s1[strlen(s1) - 1] = '\0';
if (memcmp(s1, "quit", 4) == 0)
break;
memset(s2, 0x00, sizeof(s2));
len = expand(s1, s2);
printf("====> %s\t\tlen = %d\n", s2, len);
}
return 0;
}
执行结果如下:
代码
ken@Linux:~/TCPL/chap3$ ./exe3_3
input string(a-z,0-9,.., 'quit' to exit):
a-z
====> abcdefghijklmnopqrstuvwxyz len = 26
input string(a-z,0-9,.., 'quit' to exit):
--a-b-c0-9
====> --abc0123456789 len = 15
input string(a-z,0-9,.., 'quit' to exit):
0-9
====> 0123456789 len = 10
input string(a-z,0-9,.., 'quit' to exit):
a-b-c-d-e-f-uc-u0-9
====> abcdefghijklmnopqrstucdefghijklmnopqrstu0123456789 len = 50
input string(a-z,0-9,.., 'quit' to exit):
quit
PS:刚才看了TCAB,里面的答案写得很简洁,确实是我想得复杂了,不应该把情况分得那么细。整体的思路还是一样的,重新看了自己的代码,发现有好些地方是可以省略或者归并的。下面的TCAB里面的代码,学习学习:
代码
void expand(char s1[], char s2[])
{
char c;
int i, j;
i = j = 0;
while ((c = s1[i++]) != '\0') {
if (s1[i] == '-' && s1[i+1] >= c) {
i++;
while (c < s1[i])
s2[j++] = c++;
} else
s2[j++] = c;
}
s2[j] = '\0';
}


浙公网安备 33010602011771号