TCPL练习3-3的题目是这样的:函数expand(s1, s2),将字符串中s1中类似a-z的速记扩展为:abcd...xyz,并能处理大小写,并可以处理a-b-c-d, a-z0-9, -a-z这样的情况,前导的-字符照样排印。
我记得这道题在豆瓣上看朋友用PY写得很简洁,用C写的代码看起来比较累赘,可能也是我想得比较复杂。代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#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 ;
}
#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 ;
}
执行结果如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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
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里面的代码,学习学习:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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 ' ;
}
{
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 ' ;
}