K&Rを読もう(36) 演習 3-3 aからzまで。
デジャブ?
演習 3-3
文字列s1の中のa-zのような省略記法を、それと等価な完全リストabc..xyzにしてs2の中に展開する関数expand(s1, s2)を書け。大文字、小文字、数字を許し、a-b-cやa-z0-9や-a-zのような場合も処理出来るようにせよ。先頭及び最後の-は文字とみなす。
むむぅ。ちょっと考えた。
方針
a-m-zで考えてみる。
- a-mというのがあったら、abc...jklまで展開する。ここで「mは展開しない」のがポイント。
- 次にm-zを展開し、mno...wxyまで展開。
- zを出力。
「文字-文字」という続きの場合のみ展開し、その他はそのまま出力。また、z-a,z-z等を除外する。
ソース
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #define MAX 1024 void expand(char *s, char *t, int size); int main(void) { char t[MAX]; expand("-0-9 a-m-z A-M-Z Z-A-", t, MAX); printf("%s\n", t); return EXIT_SUCCESS; } void expand(char *s, char *t, int size) { int i; char *end = t + size - 1; for (;*s != '\0'; s++) { if ((isdigit(*s) && *(s + 1) == '-' && isdigit(*(s + 2)) || isalpha(*s) && *(s + 1) == '-' && isalpha(*(s + 2))) && *s < *(s + 2)) { for (i = *s ; i < *(s + 2) && t < end; i++) *t++ = i; s++; } else { if (t < end) *t++ = *s; else break; } } *t = '\0'; }
ふ・複雑。配列でやった方が良かったかも。
実行する。
-0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ Z-A-
おぉぉぉぉ。うまくいった!!