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

回答編集履歴

5

修正

2021/01/30 11:37

投稿

kairi003
kairi003

スコア1332

answer CHANGED
@@ -3,4 +3,19 @@
3
3
  積集合は「2つの配列をそれぞれソート→小さい方から比べつつ共通の数値があったら新しい配列に入れる」というような動作になります。添字の進め方に工夫が必要なので考えてみてください。
4
4
 
5
5
  また、1~10ということがわかっているなら、ビット演算を用いることでもっと楽にできます。
6
- 0に対して元の配列から1<<(数値)との論理和を取っていけば、たとえば{1,2,3,5,5,5,8,8,9,9}なら2進数で1100101110になるので、2つの配列をこのようにint型の数値に変換してからビット論理和、論理積をそれぞれとって配列にもどせば終わりです。
6
+ 0に対して元の配列から1<<(数値)との論理和を取っていけば、たとえば{1,2,3,5,5,5,8,8,9,9}なら2進数で1100101110になるので、2つの配列をこのようにint型の数値に変換してからビット論理和、論理積をそれぞれとって配列にもどせば終わりです。
7
+
8
+ ---
9
+ 追記
10
+ 回答修正が迷走してしまってすみません。
11
+ 「重複を消す」の例はこんな感じですね
12
+ ```c
13
+ int main(void) {
14
+ int ab[20] = {1,1,2,3,3,4,5,6,7,7,7,7,7,8,8,9,9,9,9,10}; // aとbを連結してソートした配列
15
+ int or[10];
16
+ or[0] = ab[0];
17
+ for (int i=0,j=0;i<20;i++) {
18
+ if (ab[i] > or[j]) or[++j] = ab[i];
19
+ }
20
+ }
21
+ ```

4

削除

2021/01/30 11:37

投稿

kairi003
kairi003

スコア1332

answer CHANGED
@@ -1,44 +1,6 @@
1
1
  複数回あるのを除くには、ソートしてから新しい配列を用意して、元の配列の小さい方から順に、数値が大きくなったときだけ、新しい配列に数値を入れていけばいいです。
2
- ~~「2つの配列を1つにまとめる→ソート→重複を除く」で和集合はできます。~~
2
+ 「2つの配列を1つにまとめる→ソート→重複を除く」で和集合はできます。
3
3
  積集合は「2つの配列をそれぞれソート→小さい方から比べつつ共通の数値があったら新しい配列に入れる」というような動作になります。添字の進め方に工夫が必要なので考えてみてください。
4
4
 
5
5
  また、1~10ということがわかっているなら、ビット演算を用いることでもっと楽にできます。
6
- 0に対して元の配列から1<<(数値)との論理和を取っていけば、たとえば{1,2,3,5,5,5,8,8,9,9}なら2進数で1100101110になるので、2つの配列をこのようにint型の数値に変換してからビット論理和、論理積をそれぞれとって配列にもどせば終わりです。
6
+ 0に対して元の配列から1<<(数値)との論理和を取っていけば、たとえば{1,2,3,5,5,5,8,8,9,9}なら2進数で1100101110になるので、2つの配列をこのようにint型の数値に変換してからビット論理和、論理積をそれぞれとって配列にもどせば終わりです。
7
-
8
- ---
9
- 追記
10
-
11
- やっぱり和集合も積集合と同じように「2つの配列をそれぞれソート→小さい方から順に比べ、初出の数値があれば新しい配列に追加する」という方が合わせてイメージしやすいかもしれません。
12
- その場合「重複を削除」はあまり意識しなくていいです。
13
-
14
- ```c
15
- int a[10] = {...}; // ソートされた配列a
16
- int b[10] = {...}; // ソートされた配列b
17
- int or[10] = {0}; // 和集合が入る配列or
18
-
19
- int i = 0; // aの添字
20
- int j = 0; // bの添字
21
- int k = 0; // orの添字
22
- int max = 0; // orの現在の最大値(比較用)
23
-
24
- while (i < 10 || j < 10) {
25
- if (a[i] > max) {
26
- // a[i]がmaxより大きければ、orに入れる→max更新→kを+1
27
- max = a[i];
28
- or[k] = a[i];
29
- k++;
30
- } else {
31
- //max以下ならiを+1
32
- i++;
33
- };
34
- if (b[j] > max) {
35
- max = b[j];
36
- or[k] = b[j];
37
- k++;
38
- } else {
39
- j++;
40
-
41
- };
42
- ```
43
-
44
- 試してないのでちゃんと動くかは分かりませんかイメージとしては↑です。

3

修正

2021/01/30 11:14

投稿

kairi003
kairi003

スコア1332

answer CHANGED
@@ -19,18 +19,25 @@
19
19
  int i = 0; // aの添字
20
20
  int j = 0; // bの添字
21
21
  int k = 0; // orの添字
22
- int max = -1; // orの現在の最大値(比較用)
22
+ int max = 0; // orの現在の最大値(比較用)
23
23
 
24
24
  while (i < 10 || j < 10) {
25
25
  if (a[i] > max) {
26
- // a[i]がmax以上なら、orに入れる→max更新→kとiを+1
26
+ // a[i]がmaxより大きければ、orに入れる→max更新→kを+1
27
27
  max = a[i];
28
- or[k++] = a[i++];
28
+ or[k] = a[i];
29
+ k++;
30
+ } else {
31
+ //max以下ならiを+1
32
+ i++;
29
33
  };
30
34
  if (b[j] > max) {
31
35
  max = b[j];
32
- or[k++] = b[j++];
36
+ or[k] = b[j];
33
- };
37
+ k++;
38
+ } else {
39
+ j++;
40
+
34
41
  };
35
42
  ```
36
43
 

2

修正

2021/01/30 10:57

投稿

kairi003
kairi003

スコア1332

answer CHANGED
@@ -21,7 +21,7 @@
21
21
  int k = 0; // orの添字
22
22
  int max = -1; // orの現在の最大値(比較用)
23
23
 
24
- while (i < 10 || < || 10) {
24
+ while (i < 10 || j < 10) {
25
25
  if (a[i] > max) {
26
26
  // a[i]がmax以上なら、orに入れる→max更新→kとiを+1
27
27
  max = a[i];

1

追記

2021/01/30 10:51

投稿

kairi003
kairi003

スコア1332

answer CHANGED
@@ -1,6 +1,37 @@
1
1
  複数回あるのを除くには、ソートしてから新しい配列を用意して、元の配列の小さい方から順に、数値が大きくなったときだけ、新しい配列に数値を入れていけばいいです。
2
- 「2つの配列を1つにまとめる→ソート→重複を除く」で和集合はできます。
2
+ ~~「2つの配列を1つにまとめる→ソート→重複を除く」で和集合はできます。~~
3
3
  積集合は「2つの配列をそれぞれソート→小さい方から比べつつ共通の数値があったら新しい配列に入れる」というような動作になります。添字の進め方に工夫が必要なので考えてみてください。
4
4
 
5
5
  また、1~10ということがわかっているなら、ビット演算を用いることでもっと楽にできます。
6
- 0に対して元の配列から1<<(数値)との論理和を取っていけば、たとえば{1,2,3,5,5,5,8,8,9,9}なら2進数で1100101110になるので、2つの配列をこのようにint型の数値に変換してからビット論理和、論理積をそれぞれとって配列にもどせば終わりです。
6
+ 0に対して元の配列から1<<(数値)との論理和を取っていけば、たとえば{1,2,3,5,5,5,8,8,9,9}なら2進数で1100101110になるので、2つの配列をこのようにint型の数値に変換してからビット論理和、論理積をそれぞれとって配列にもどせば終わりです。
7
+
8
+ ---
9
+ 追記
10
+
11
+ やっぱり和集合も積集合と同じように「2つの配列をそれぞれソート→小さい方から順に比べ、初出の数値があれば新しい配列に追加する」という方が合わせてイメージしやすいかもしれません。
12
+ その場合「重複を削除」はあまり意識しなくていいです。
13
+
14
+ ```c
15
+ int a[10] = {...}; // ソートされた配列a
16
+ int b[10] = {...}; // ソートされた配列b
17
+ int or[10] = {0}; // 和集合が入る配列or
18
+
19
+ int i = 0; // aの添字
20
+ int j = 0; // bの添字
21
+ int k = 0; // orの添字
22
+ int max = -1; // orの現在の最大値(比較用)
23
+
24
+ while (i < 10 || < || 10) {
25
+ if (a[i] > max) {
26
+ // a[i]がmax以上なら、orに入れる→max更新→kとiを+1
27
+ max = a[i];
28
+ or[k++] = a[i++];
29
+ };
30
+ if (b[j] > max) {
31
+ max = b[j];
32
+ or[k++] = b[j++];
33
+ };
34
+ };
35
+ ```
36
+
37
+ 試してないのでちゃんと動くかは分かりませんかイメージとしては↑です。