输出中的重复信息
alvits 当前接受的answer 会生成大量重复输出,其中组合是相同边组合的排列。我修改了代码以打印周长从 3 到 29 的所有三角形,并在打印操作之前添加了建议的条件 if (a <= b && b <= c)。
tp17.c
注意:代码不正确。
#include <stdio.h>
int main(void)
{
int p, a, b, c;
// printf("Enter a perimeter: ");
// scanf("%d", &p);
for (p = 3; p < 30; p++)
{
printf("Triangles with perimeter: %d\n", p);
for (a = 1; 2 * a < p; a++)
{
for (b = (p - a) / 2; (p - 2 * a) > 0 && (p - 2 * b) > 0 && (2 * a + 2 * b - p) > 0; b++)
{
c = p - (a + b);
if (a <= b && b <= c)
printf("%d, %d, %d\n", a, b, c);
}
}
}
return 0;
}
结果的printf() 之前的条件if (a <=b && b <= c) 旨在确保您只生成每个长度组合一次。我注意到,例如,当 p = 12 时,您会得到:(2, 5, 5)、(3, 4, 5)、(4, 4, 4) 作为输出。我错过的是p = 11,添加条件省略(3, 5, 3)(因为代码不会生成(3, 3, 5),原因我无法理解)。所以,条件不够好——它确实消除了很多重复的条目(好),但也丢弃了一些非重复的条目(坏)。
因此,代码应该消除条件,这会使程序产生大量冗余输出,大大复杂输出比较。
tp13.c
我还创建了一个密切相关的程序,从相同的基础开始:
#include <stdio.h>
int main(void)
{
for (int p = 3; p < 30; p++)
{
printf("Triangles with perimeter: %d\n", p);
for (int a = 1; a <= p / 2; a++)
{
for (int b = 1; b + a < p; b++)
{
int c = p - (a + b);
if (a + b <= c || a + c <= b || b + c <= a)
continue;
if (a <= b && b <= c)
printf("%d, %d, %d\n", a, b, c);
}
}
}
return 0;
}
输出比较
比较tp13 和tp17 输出的部分diff -u 输出是:
Triangles with perimeter: 11
1, 5, 5
2, 4, 5
-3, 3, 5
+2, 5, 4
3, 4, 4
+3, 5, 3
+4, 3, 4
+4, 4, 3
+4, 5, 2
+5, 3, 3
+5, 4, 2
+5, 5, 1
Triangles with perimeter: 12
2, 5, 5
3, 4, 5
+3, 5, 4
4, 4, 4
+4, 5, 3
+5, 3, 4
+5, 4, 3
+5, 5, 2
Triangles with perimeter: 13
查看 12 周长的结果,很明显tp17 只是生成不同的排列。但是,查看周长 11 的结果表明 tp17 生成 (3, 5, 3) 和 (5, 3, 3) 但不是 (3, 3, 5) 而 tp13 生成 (3, 3, 5) 而不是其他两个排列。但是,显示的输出片段中tp17 的输出中的所有其他额外行都是其他行的排列。
需要不同的输出格式
上面的输出格式不适合自动比较,所以我修改了输出以打印周长,然后是按非递减顺序列出的三个边。因此,我在tp17.c 中添加了代码,以便在打印前将边排序为非递减顺序。对于三个元素,可能有更简单的方法,但这是可行的。
tp47.c
/* SO 4203-5818 - Calculate all triangles with given perimeter */
#include <stdio.h>
#include <stdlib.h>
static int int_cmp(const void *va, const void *vb)
{
int a = *(int *)va;
int b = *(int *)vb;
return (a > b) - (a < b);
}
int main(void)
{
int p, a, b, c;
for (p = 3; p < 30; p++)
{
for (a = 1; 2 * a < p; a++)
{
for (b = (p - a) / 2; (p - 2 * a) > 0 && (p - 2 * b) > 0 && (2 * a + 2 * b - p) > 0; b++)
{
c = p - (a + b);
{
int d[] = { a, b, c };
qsort(d, 3, sizeof(d[0]), int_cmp);
printf("%d: %d, %d, %d\n", p, d[0], d[1], d[2]);
}
}
}
}
return 0;
}
tp43.c
/* SO 4203-5818 - Calculate all triangles with given perimeter */
#include <stdio.h>
int main(void)
{
for (int p = 3; p < 30; p++)
{
for (int a = 1; a <= p / 2; a++)
{
for (int b = 1; b + a < p; b++)
{
int c = p - (a + b);
if (a + b <= c || a + c <= b || b + c <= a)
continue;
if (a <= b && b <= c)
printf("%d: %d, %d, %d\n", p, a, b, c);
}
}
}
return 0;
}
(除打印外,与tp13.c相同。)
比较
现在可以对输出进行排序和比较。 tp43 的 -u 选项是多余但对称的。
$ tp43 | sort -u -k1n -k2n -k3n -k4n > tp43.out
$ tp47 | sort -u -k1n -k2n -k3n -k4n > tp47.out
$ diff tp43.out tp47.out
$
因此,唯一的输出是相同的,但是当您计算差异时,tp47 的输出中有 390 行额外的行:
$ tp43 | sort -k1n -k2n -k3n -k4n > tp43-all.out
$ tp47 | sort -k1n -k2n -k3n -k4n > tp47-all.out
$ diff tp43-all.out tp47-all.out | diffcount
deleted 0, inserted 390
$ wc -l tp4?.out tp4?-all.out
206 tp43.out
206 tp47.out
206 tp43-all.out
596 tp47-all.out
1214 total
$
仅作记录,文件tp43.out、tp47.out、tp43-all.out 是相同的。他们的内容是:
3: 1, 1, 1
5: 1, 2, 2
6: 2, 2, 2
7: 1, 3, 3
7: 2, 2, 3
8: 2, 3, 3
9: 1, 4, 4
9: 2, 3, 4
9: 3, 3, 3
10: 2, 4, 4
10: 3, 3, 4
11: 1, 5, 5
11: 2, 4, 5
11: 3, 3, 5
11: 3, 4, 4
12: 2, 5, 5
12: 3, 4, 5
12: 4, 4, 4
13: 1, 6, 6
13: 2, 5, 6
13: 3, 4, 6
13: 3, 5, 5
13: 4, 4, 5
14: 2, 6, 6
14: 3, 5, 6
14: 4, 4, 6
14: 4, 5, 5
15: 1, 7, 7
15: 2, 6, 7
15: 3, 5, 7
15: 3, 6, 6
15: 4, 4, 7
15: 4, 5, 6
15: 5, 5, 5
16: 2, 7, 7
16: 3, 6, 7
16: 4, 5, 7
16: 4, 6, 6
16: 5, 5, 6
17: 1, 8, 8
17: 2, 7, 8
17: 3, 6, 8
17: 3, 7, 7
17: 4, 5, 8
17: 4, 6, 7
17: 5, 5, 7
17: 5, 6, 6
18: 2, 8, 8
18: 3, 7, 8
18: 4, 6, 8
18: 4, 7, 7
18: 5, 5, 8
18: 5, 6, 7
18: 6, 6, 6
19: 1, 9, 9
19: 2, 8, 9
19: 3, 7, 9
19: 3, 8, 8
19: 4, 6, 9
19: 4, 7, 8
19: 5, 5, 9
19: 5, 6, 8
19: 5, 7, 7
19: 6, 6, 7
20: 2, 9, 9
20: 3, 8, 9
20: 4, 7, 9
20: 4, 8, 8
20: 5, 6, 9
20: 5, 7, 8
20: 6, 6, 8
20: 6, 7, 7
21: 1, 10, 10
21: 2, 9, 10
21: 3, 8, 10
21: 3, 9, 9
21: 4, 7, 10
21: 4, 8, 9
21: 5, 6, 10
21: 5, 7, 9
21: 5, 8, 8
21: 6, 6, 9
21: 6, 7, 8
21: 7, 7, 7
22: 2, 10, 10
22: 3, 9, 10
22: 4, 8, 10
22: 4, 9, 9
22: 5, 7, 10
22: 5, 8, 9
22: 6, 6, 10
22: 6, 7, 9
22: 6, 8, 8
22: 7, 7, 8
23: 1, 11, 11
23: 2, 10, 11
23: 3, 9, 11
23: 3, 10, 10
23: 4, 8, 11
23: 4, 9, 10
23: 5, 7, 11
23: 5, 8, 10
23: 5, 9, 9
23: 6, 6, 11
23: 6, 7, 10
23: 6, 8, 9
23: 7, 7, 9
23: 7, 8, 8
24: 2, 11, 11
24: 3, 10, 11
24: 4, 9, 11
24: 4, 10, 10
24: 5, 8, 11
24: 5, 9, 10
24: 6, 7, 11
24: 6, 8, 10
24: 6, 9, 9
24: 7, 7, 10
24: 7, 8, 9
24: 8, 8, 8
25: 1, 12, 12
25: 2, 11, 12
25: 3, 10, 12
25: 3, 11, 11
25: 4, 9, 12
25: 4, 10, 11
25: 5, 8, 12
25: 5, 9, 11
25: 5, 10, 10
25: 6, 7, 12
25: 6, 8, 11
25: 6, 9, 10
25: 7, 7, 11
25: 7, 8, 10
25: 7, 9, 9
25: 8, 8, 9
26: 2, 12, 12
26: 3, 11, 12
26: 4, 10, 12
26: 4, 11, 11
26: 5, 9, 12
26: 5, 10, 11
26: 6, 8, 12
26: 6, 9, 11
26: 6, 10, 10
26: 7, 7, 12
26: 7, 8, 11
26: 7, 9, 10
26: 8, 8, 10
26: 8, 9, 9
27: 1, 13, 13
27: 2, 12, 13
27: 3, 11, 13
27: 3, 12, 12
27: 4, 10, 13
27: 4, 11, 12
27: 5, 9, 13
27: 5, 10, 12
27: 5, 11, 11
27: 6, 8, 13
27: 6, 9, 12
27: 6, 10, 11
27: 7, 7, 13
27: 7, 8, 12
27: 7, 9, 11
27: 7, 10, 10
27: 8, 8, 11
27: 8, 9, 10
27: 9, 9, 9
28: 2, 13, 13
28: 3, 12, 13
28: 4, 11, 13
28: 4, 12, 12
28: 5, 10, 13
28: 5, 11, 12
28: 6, 9, 13
28: 6, 10, 12
28: 6, 11, 11
28: 7, 8, 13
28: 7, 9, 12
28: 7, 10, 11
28: 8, 8, 12
28: 8, 9, 11
28: 8, 10, 10
28: 9, 9, 10
29: 1, 14, 14
29: 2, 13, 14
29: 3, 12, 14
29: 3, 13, 13
29: 4, 11, 14
29: 4, 12, 13
29: 5, 10, 14
29: 5, 11, 13
29: 5, 12, 12
29: 6, 9, 14
29: 6, 10, 13
29: 6, 11, 12
29: 7, 8, 14
29: 7, 9, 13
29: 7, 10, 12
29: 7, 11, 11
29: 8, 8, 13
29: 8, 9, 12
29: 8, 10, 11
29: 9, 9, 11
29: 9, 10, 10