teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

追加

2020/09/02 13:18

投稿

amiya
amiya

スコア1218

answer CHANGED
@@ -23,4 +23,76 @@
23
23
  つまり、**ポインタの指すアドレスに、データを書き込み、さらに、ポインタを次に進める**という内容となります。
24
24
 
25
25
  内容としては、
26
- `*string = 'A';`に続いて`string++;`をしたのと同じになります。
26
+ `*string = 'A';`に続いて`string++;`をしたのと同じになります。
27
+
28
+
29
+ ---
30
+
31
+ 全体の流れが判りやすいようにコメントを付けます。
32
+
33
+ ```C
34
+ #include <string.h>
35
+ #include <stdlib.h> //malloc
36
+
37
+ char* get_strings(const char *city)
38
+ {
39
+ int i, j, n;
40
+ n = strlen(city);
41
+ char *string;
42
+ string = malloc( n * 4 + 1);
43
+ char *base = string;
44
+
45
+ for(i = 0; i < n; i++ ) //元の文字列から一つずつ文字をとる
46
+ {
47
+
48
+ int count = 0;
49
+ int count2 = 0;
50
+
51
+ for(j = 0; j < n; j++) //元の文字列の中に同じ文字があるかカウント
52
+ {
53
+ if(city[i] == city[j])count++; //自分があるので最低1以上
54
+ }
55
+
56
+ *string++ = city[i]; //全ての文字を無条件で提示用に登録
57
+ *string++ = ':';
58
+
59
+ if(i > 0) //iが1以上なら=1文字目だけを除いて以下を処理
60
+ {
61
+ for(int b = i - 1; b == 0; b--) //今の文字より前の文字を調べる
62
+ {
63
+ if(city[i] == city[b])count2++; //同じ文字があればカウント
64
+ }
65
+ }
66
+
67
+
68
+ if(count2 != 0) //自分より前に同じ文字があれば
69
+ {
70
+ for(int a = 1; a == count; a++) //カウントした数だけ
71
+ {
72
+ *string++ ='*'; //*を付ける
73
+ }
74
+
75
+ if(i != (n -1)) //最後の文字以外なら
76
+ {
77
+ *string++ = ','; //,を付ける
78
+ }
79
+ else if(i == (n - 1))       //最後の文字以外ではなく最後の文字なら(if不要)
80
+ {
81
+ *string++ = '\0'; //末端文字を付ける
82
+ }
83
+ }
84
+ }
85
+ return base;
86
+ }
87
+ ```
88
+
89
+ まずは、大文字と小文字を区別しないという処理がありません。
90
+ 次に、表示用文字列に対して、文字を登録する時に、問答無用で登録してしまっているので、
91
+ `C:h:i:c:a:g:o:`の様に、二つ目の`c`が登場してしまっています。
92
+ 2つ以上ある文字の2度目の登場はスルーする必要があります。
93
+
94
+ `*`が出ないのは、`*`を出すかを決める条件が、「自分よりも前に同じ文字が1つ以上あれば」となっています。
95
+ Chicagoの文字列の中で、大文字小文字を区別した場合、「自分よりも前に同じ文字が1つ以上」あるものは存在しないので、`*`が表示されません。
96
+ 「自分よりも前に同じ文字が1つ以上あれば、その数の`*`を表示する」ではなく、
97
+ 「文字列の中に自分と同じ文字があった数の`*`を表示する」とする必要があります。
98
+ (自分自身を含むので必ず1以上の`*`は付きます)