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

回答編集履歴

7

バグ修正

2021/02/05 09:49

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -108,8 +108,10 @@
108
108
  if (a2[j] != t) b[k++] = t = a2[j];
109
109
  j++;
110
110
  }
111
+ for (; i < N; i++)
111
- while (i < N) b[k++] = a1[i++];
112
+ if (a1[i] != t) b[k++] = t = a1[i];
113
+ for (; j < N; j++)
112
- while (j < N) b[k++] = a2[j++];
114
+ if (a2[j] != t) b[k++] = t = a2[j];
113
115
  return k;
114
116
  }
115
117
 

6

コードの改善

2021/02/05 09:49

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -105,11 +105,9 @@
105
105
  i++;
106
106
  }
107
107
  else {
108
- if (a1[i] == a2[j]) i++;
109
108
  if (a2[j] != t) b[k++] = t = a2[j];
110
109
  j++;
111
110
  }
112
-
113
111
  while (i < N) b[k++] = a1[i++];
114
112
  while (j < N) b[k++] = a2[j++];
115
113
  return k;

5

コードの改善

2021/01/31 18:57

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -104,14 +104,12 @@
104
104
  if (a1[i] != t) b[k++] = t = a1[i];
105
105
  i++;
106
106
  }
107
+ else {
107
- else if (a1[i] > a2[j]) {
108
+ if (a1[i] == a2[j]) i++;
108
109
  if (a2[j] != t) b[k++] = t = a2[j];
109
110
  j++;
110
111
  }
111
- else {
112
+
112
- if (a1[i] != t) b[k++] = t = a1[i];
113
- i++, j++;
114
- }
115
113
  while (i < N) b[k++] = a1[i++];
116
114
  while (j < N) b[k++] = a2[j++];
117
115
  return k;

4

ソートを使うコードを追加

2021/01/31 18:05

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -54,4 +54,92 @@
54
54
  }
55
55
  ```
56
56
  ビット演算を使わなければ理解できるのでしょうか?
57
- コメントをお願いします。
57
+ コメントをお願いします。
58
+
59
+ **追記2**
60
+ ソートした 2つの配列を先頭から見ていって、積集合と和集合を求めるやり方。
61
+ ```C
62
+ #include <stdio.h>
63
+
64
+ #define N 10 // 配列の要素数
65
+ #define A 1 // 要素の値の範囲 A以上 B以下
66
+ #define B 10
67
+
68
+ void print(int a[], int n)
69
+ {
70
+ for (int i = 0; i < n; i++)
71
+ printf(" %d", a[i]);
72
+ putchar('\n');
73
+ }
74
+
75
+ void sort(int a[])
76
+ {
77
+ for (int i = 0; i < N-1; i++)
78
+ for (int j = i+1; j < N; j++)
79
+ if (a[i] > a[j]) {
80
+ int t = a[i]; a[i] = a[j]; a[j] = t;
81
+ }
82
+ }
83
+
84
+ int intersection(int a1[], int a2[], int b[])
85
+ {
86
+ int i = 0, j = 0, k = 0, t = A-1;
87
+ while (i < N && j < N)
88
+ if (a1[i] < a2[j])
89
+ i++;
90
+ else if (a1[i] > a2[j])
91
+ j++;
92
+ else {
93
+ if (a1[i] != t) b[k++] = t = a1[i];
94
+ i++, j++;
95
+ }
96
+ return k;
97
+ }
98
+
99
+ int union_set(int a1[], int a2[], int b[])
100
+ {
101
+ int i = 0, j = 0, k = 0, t = A-1;
102
+ while (i < N && j < N)
103
+ if (a1[i] < a2[j]) {
104
+ if (a1[i] != t) b[k++] = t = a1[i];
105
+ i++;
106
+ }
107
+ else if (a1[i] > a2[j]) {
108
+ if (a2[j] != t) b[k++] = t = a2[j];
109
+ j++;
110
+ }
111
+ else {
112
+ if (a1[i] != t) b[k++] = t = a1[i];
113
+ i++, j++;
114
+ }
115
+ while (i < N) b[k++] = a1[i++];
116
+ while (j < N) b[k++] = a2[j++];
117
+ return k;
118
+ }
119
+
120
+ int main(void)
121
+ {
122
+ int a1[N] = { 5, 8, 4, 3, 7, 9, 7, 9, 5, 1 };
123
+ int a2[N] = { 7, 6, 1, 5, 9, 9, 10, 8, 4, 3 };
124
+ printf("配列1:"), print(a1, N);
125
+ printf("配列2:"), print(a2, N);
126
+ sort(a1);
127
+ printf("配列1(昇順):"), print(a1, N);
128
+ sort(a2);
129
+ printf("配列2(昇順):"), print(a2, N);
130
+ int b[B-A+1], n;
131
+ n = intersection(a1, a2, b);
132
+ printf("共通する数:"), print(b, n);
133
+ n = union_set(a1, a2, b);
134
+ printf("どちらかにある数:"), print(b, n);
135
+ }
136
+ ```
137
+ 実行結果
138
+ ```text
139
+ 配列1: 5 8 4 3 7 9 7 9 5 1
140
+ 配列2: 7 6 1 5 9 9 10 8 4 3
141
+ 配列1(昇順): 1 3 4 5 5 7 7 8 9 9
142
+ 配列2(昇順): 1 3 4 5 6 7 8 9 9 10
143
+ 共通する数: 1 3 4 5 7 8 9
144
+ どちらかにある数: 1 3 4 5 6 7 8 9 10
145
+ ```

3

コードの修正

2021/01/31 17:56

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -43,7 +43,7 @@
43
43
  {
44
44
  int a1[N] = { 5, 8, 4, 3, 7, 9, 7, 9, 5, 1 };
45
45
  int a2[N] = { 7, 6, 1, 5, 9, 9, 10, 8, 4, 3 };
46
- int b1[B] = { 0 }, b2[B] = { 0 }, c[B+1] = { 0 }, d[B+1] = { 0 };
46
+ int b1[B+1] = { 0 }, b2[B+1] = { 0 }, c[B+1] = { 0 }, d[B+1] = { 0 };
47
47
  for (int i = 0; i < N; i++) b1[a1[i]] = b2[a2[i]] = 1;
48
48
  for (int i = A; i <= B; i++) {
49
49
  c[i] = b1[i] * b2[i]; // 積集合

2

ビット演算を使わないコードを追加

2021/01/30 13:49

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -22,4 +22,36 @@
22
22
  printf("共通する数:"), print(b1 & b2);
23
23
  printf("どちらかにある数:"), print(b1 | b2);
24
24
  }
25
- ```
25
+ ```
26
+ **追記**
27
+ ビット演算を使わないやり方です。
28
+ ```C
29
+ #include <stdio.h>
30
+
31
+ #define N 10 // 配列の要素数
32
+ #define A 1 // 要素の値の範囲 A以上 B以下
33
+ #define B 10
34
+
35
+ void print(int b[B+1])
36
+ {
37
+ for (int i = A; i <= B; i++)
38
+ if (b[i]) printf(" %d", i);
39
+ putchar('\n');
40
+ }
41
+
42
+ int main(void)
43
+ {
44
+ int a1[N] = { 5, 8, 4, 3, 7, 9, 7, 9, 5, 1 };
45
+ int a2[N] = { 7, 6, 1, 5, 9, 9, 10, 8, 4, 3 };
46
+ int b1[B] = { 0 }, b2[B] = { 0 }, c[B+1] = { 0 }, d[B+1] = { 0 };
47
+ for (int i = 0; i < N; i++) b1[a1[i]] = b2[a2[i]] = 1;
48
+ for (int i = A; i <= B; i++) {
49
+ c[i] = b1[i] * b2[i]; // 積集合
50
+ d[i] = b1[i] + b2[i]; // 和集合
51
+ }
52
+ printf("共通する数:"), print(c);
53
+ printf("どちらかにある数:"), print(d);
54
+ }
55
+ ```
56
+ ビット演算を使わなければ理解できるのでしょうか?
57
+ コメントをお願いします。

1

10の意味の違いが分かるようにコードを修正

2021/01/30 12:10

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -2,19 +2,23 @@
2
2
  ```C
3
3
  #include <stdio.h>
4
4
 
5
+ #define N 10 // 配列の要素数
6
+ #define A 1 // 要素の値の範囲 A以上 B以下
7
+ #define B 10
8
+
5
9
  void print(int b)
6
10
  {
7
- for (int i = 1; i <= 10; i++)
11
+ for (int i = A; i <= B; i++)
8
12
  if (b >> i & 1) printf(" %d", i);
9
13
  putchar('\n');
10
14
  }
11
15
 
12
16
  int main(void)
13
17
  {
14
- int a1[] = { 5, 8, 4, 3, 7, 9, 7, 9, 5, 1 };
18
+ int a1[N] = { 5, 8, 4, 3, 7, 9, 7, 9, 5, 1 };
15
- int a2[] = { 7, 6, 1, 5, 9, 9, 10, 8, 4, 3 };
19
+ int a2[N] = { 7, 6, 1, 5, 9, 9, 10, 8, 4, 3 };
16
20
  int b1 = 0, b2 = 0;
17
- for (int i = 0; i < 10; i++) b1 |= 1 << a1[i], b2 |= 1 << a2[i];
21
+ for (int i = 0; i < N; i++) b1 |= 1 << a1[i], b2 |= 1 << a2[i];
18
22
  printf("共通する数:"), print(b1 & b2);
19
23
  printf("どちらかにある数:"), print(b1 | b2);
20
24
  }