回答編集履歴
2
'z' の値がタイポ
test
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
|
13
13
|
'a' == 0x61 == 97
|
14
14
|
|
15
|
-
'z' == 0x7a == 1
|
15
|
+
'z' == 0x7a == 122 です。
|
16
16
|
|
17
17
|
アルファベットは 'a' ~ 'z' の26文字あるので、出現回数を保持する配列の要素数は26必要です。したがって int c[26]; としたい。
|
18
18
|
|
@@ -46,7 +46,7 @@
|
|
46
46
|
|
47
47
|
ここは、要素数26の配列を定義して(メモリを割り当てて)、その全ての要素を0で初期化しています。
|
48
48
|
|
49
|
-
- INDEX('z'+1) => 'z' + 1 - 'a' => 1
|
49
|
+
- INDEX('z'+1) => 'z' + 1 - 'a' => 122 + 1 - 97 => 26 であるから、
|
50
50
|
|
51
51
|
int c[INDEX('z' + 1)] は int c[26] と展開される。めでたしめでたし(アルファベットが26文字であることは常識の範疇だから最初から int c[26] = {0}; としても構わないと思う)。
|
52
52
|
|
1
説明を補足修正
test
CHANGED
@@ -1,50 +1,58 @@
|
|
1
1
|
int main(int argc, char *argv[]) {
|
2
2
|
|
3
|
-
main()関数、戻り値の型と引数の型を示している…程度でよさそうですね。
|
3
|
+
main()関数の冒頭部分で、戻り値の型と引数の型を示している…程度でよさそうですね。
|
4
4
|
|
5
5
|
|
6
6
|
|
7
7
|
``` #define INDEX(x) (x-'a') ```
|
8
8
|
|
9
|
+
|
10
|
+
|
11
|
+
前提となる[アスキーコード表](http://www3.nit.ac.jp/~tamura/ex2/ascii.html)を確認すると
|
12
|
+
|
9
13
|
'a' == 0x61 == 97
|
10
14
|
|
11
15
|
'z' == 0x7a == 112 です。
|
12
16
|
|
13
|
-
アルファベット 'a' ~ 'z' の26文字あるので、出現回数を保持する配列の要素数は26必要です。したがって
|
17
|
+
アルファベットは 'a' ~ 'z' の26文字あるので、出現回数を保持する配列の要素数は26必要です。したがって int c[26]; としたい。
|
14
|
-
|
15
|
-
int c[26]; としたい。
|
16
18
|
|
17
19
|
|
18
20
|
|
19
|
-
そのうえで、例えば'a' の出現回数を c['a']
|
21
|
+
そのうえで、例えば'a' の出現回数を c['a'] とでもしたいところですが、それだと c[97] となってしまってダメ。そこで
|
20
22
|
|
21
|
-
'a' => 0
|
23
|
+
'a' => 0 (== 'a' - 'a')
|
22
24
|
|
23
|
-
'b' => 1
|
25
|
+
'b' => 1 (== 'b' - 'a')
|
24
26
|
|
25
27
|
:
|
26
28
|
|
27
|
-
'z' => 25
|
29
|
+
'z' => 25 (== 'z' - 'a')
|
28
30
|
|
29
|
-
と変換
|
31
|
+
と変換するマクロ INDEX(x) を作ればよい。見ての通り、INDEX(x) マクロは (x - 'a') を計算すれば良いことがわかる。
|
30
32
|
|
33
|
+
INDEX(x) マクロを作れば
|
34
|
+
|
31
|
-
c[INDEX(tolower(ch))]++
|
35
|
+
c[INDEX(tolower(ch))]++
|
32
36
|
|
33
37
|
はchの値が文字コード('a' なら97)のまま、その文字の出現回数を+1できます。
|
34
38
|
|
39
|
+
念のため:tolower(ch) は、ch が英大文字であれば小文字に(例えば 'A' を 'a' に)、英小文字はそのまま小文字に変換します。つまり 'A' も 'a' も同じ文字とみなすことになります。
|
35
40
|
|
36
41
|
|
42
|
+
|
37
|
-
int c[INDEX('z'+1)]={0};
|
43
|
+
int c[INDEX('z' + 1)] = {0};
|
38
44
|
|
39
45
|
|
40
46
|
|
41
47
|
ここは、要素数26の配列を定義して(メモリを割り当てて)、その全ての要素を0で初期化しています。
|
42
48
|
|
43
|
-
- INDEX('z'+1) => 'z' + 1 - 'a' => 112 + 1 - 97 => 26
|
49
|
+
- INDEX('z'+1) => 'z' + 1 - 'a' => 112 + 1 - 97 => 26 であるから、
|
44
50
|
|
45
|
-
|
51
|
+
int c[INDEX('z' + 1)] は int c[26] と展開される。めでたしめでたし(アルファベットが26文字であることは常識の範疇だから最初から int c[26] = {0}; としても構わないと思う)。
|
46
52
|
|
53
|
+
- int c[INDEX('z'+1)]; としただけだと、メモリは割当られるが、値は不定になってしまう。各文字の出現回数を数えるには、最初の値をすべてを0にしておく(0に初期化する)必要がある。
|
54
|
+
|
47
|
-
- 「= {0}」 の部分で配列の全ての値を0で初期化する。ここに「
|
55
|
+
- 「= {0}」 の部分で配列の全ての値を0で初期化する。ここに「0」は一個しか書かれていないので c[0] = 0 だけが初期化されるかと思うと、さにあらず。初期値の指定がある場合、初期値が省略された c[1] ~ c[25] も初期値を0にするという約束なので。
|
48
56
|
|
49
57
|
|
50
58
|
|