的主要问题是在第二次分配索引该Join()
功能的循环:
int Join(set arr1[], int arr1_size, set arr2[], int arr2_size, set arr3[], int arr3_size)
{
int i;
for (i = 0; i < arr1_size; i++)
arr3[i] = arr1[i];
for (i = 0; i < arr2_size; i++)
{
if (!in_arr(arr2[i], arr3, arr3_size))
arr3[i+arr1_size] = arr2[i];
}
}
你必须保持穿过arr3
阵列正确的进行,即使i
重置为零(和一些i
值不加)计数器。该函数被声明为返回一个值,但不这样做 - 另一个错误。返回结果数组的实际大小(如下所示)或声明函数返回void
。由于没有使用返回的值,因此第二个选项可能会更好。这可能做的工作:
int Join(set arr1[], int arr1_size, set arr2[], int arr2_size, set arr3[], int arr3_size)
{
int i;
int k = 0;
for (i = 0; i < arr1_size; i++)
arr3[k++] = arr1[i];
for (i = 0; i < arr2_size; i++)
{
if (!in_arr(arr2[i], arr3, arr3_size))
arr3[k++] = arr2[i];
}
assert(k <= arr3_size);
return k;
}
一个次要(性能而非正确性)的问题:
int newsize = 0;
for (i = 0; i < arr1_size; i++)
{
if (!in_arr(arr1[i], arr2, arr2_size))
newsize++;
}
for (i = 0; i < arr2_size; i++)
newsize++;
第二个循环可更简洁地写为:
newsize += arr2_size;
,或者更确切地说,你可以初始化newsize = arr2_size;
,然后计算额外值。
int newsize = arr2_size;
for (i = 0; i < arr1_size; i++)
{
if (!in_arr(arr1[i], arr2, arr2_size))
newsize++;
}
有一个可疑的printf()
声明arr_in_arr()
:
int arr_in_arr(set smaller[], int smaller_size, set bigger[], int bigger_size)
{
int res = 1;
int counter;
for (counter = 0; counter < smaller_size; counter++)
{
if (in_arr(smaller[counter], bigger, bigger_size))
printf("%d ", smaller[counter]);
else
{
res = 0;
break;
}
}
return res;
}
不是,它应该有“%d
”格式的字符串或条件应该被反转和整体功能的简化:
int arr_in_arr(set smaller[], int smaller_size, set bigger[], int bigger_size)
{
int counter;
for (counter = 0; counter < smaller_size; counter++)
{
if (!in_arr(smaller[counter], bigger, bigger_size))
return 0;
}
return 1;
}
变量counter
in main()
未被使用。
从结构上看,你的'集合'抽象不是很大;每次调用函数时都必须传递一个数组和一个大小。此外,你可以有一个变量set x;
其中包含一个单一的元素(而不是一组)。你可以用一个结构来改进它,但这可能会导致你暂时分配过多的内存。
也没有代码来确保这些集合不包含重复项。也就是说,如果定义了一组:
set D[] = { a, c, a, d };
的结果集Join()
操作,其中,这是左(第一)操作数将包含两个元素a
在输出中。顺便说一句,Join()
操作也可以被视为一个集合,a ∪ b
。
我结束了这段代码:
#include <stdio.h>
#include <assert.h>
#define SIZEOF_A 6
#define SIZEOF_B 6
typedef enum
{
a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
} set;
static void dispSet(set numbers[], int size_numbers)
{
int i;
printf("[ ");
for (i = 0; i < size_numbers-1; i++)
printf("%d, ", numbers[i]);
printf("%d ]", numbers[size_numbers-1]);
printf("\n");
}
static int in_arr(set A, set B[], int B_size)
{
int res = 0; // XXX: uninitialized
int counter;
for (counter = 0; counter < B_size; counter++)
{
if (A == B[counter])
{
res = 1;
break;
}
}
return res;
}
static int arr_in_arr(set smaller[], int smaller_size, set bigger[], int bigger_size)
{
int counter; // XXX: simplified
for (counter = 0; counter < smaller_size; counter++)
{
if (!in_arr(smaller[counter], bigger, bigger_size))
return 0;
}
return 1;
}
static int size_c(set arr1[], int arr1_size, set arr2[], int arr2_size)
{
int i;
int newsize = arr2_size; // XXX: compacted
for (i = 0; i < arr1_size; i++)
{
if (!in_arr(arr1[i], arr2, arr2_size))
newsize++;
}
printf("\nSIZE OF C: %d\n", newsize);
return newsize;
}
static int Join(set arr1[], int arr1_size, set arr2[], int arr2_size, set arr3[], int arr3_size)
{
int i;
int k; // XXX: fixed
for (i = 0; i < arr1_size; i++)
arr3[k++] = arr1[i];
for (i = 0; i < arr2_size; i++)
{
if (!in_arr(arr2[i], arr3, arr3_size))
arr3[k++] = arr2[i];
}
assert(k <= arr3_size);
return k;
}
int main(void)
{
set A[SIZEOF_A] = {c, d, f, a, b, j};
set B[SIZEOF_B] = {a, b, c, d, e, f};
int SIZEOF_C = size_c(A, SIZEOF_A, B, SIZEOF_B);
printf("For the sets,\n");
printf("A: ");
dispSet(A, SIZEOF_A);
printf("B: ");
dispSet(B, SIZEOF_B);
printf("C: ");
set C[SIZEOF_C];
Join(A, SIZEOF_A, B, SIZEOF_B, C, SIZEOF_C);
dispSet(C, SIZEOF_C);
printf("%s\n", (arr_in_arr(A, SIZEOF_A, B, SIZEOF_B) == 1)?"B contains A":"B does not contain A");
}
的功能是由静态的,因为使用它们,也没有任何标题宣称他们没有其他的文件(以及从-Wmissing-prototypes
关闭了编译器警告) 。 我用它编译(在使用苹果的GCC 4.2.1的MacOS X 10.6.7):
gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes join.c -o join
输出是:
SIZE OF C: 7
For the sets,
A: [ 2, 3, 5, 0, 1, 9 ]
B: [ 0, 1, 2, 3, 4, 5 ]
C: [ 2, 3, 5, 0, 1, 9, 4 ]
B does not contain A
并没有进一步看起来比'in_arr'。你错过了'res'的初始化。 – pmg 2011-05-01 18:48:48
好吧我添加了初始化,已编译,并且所有更改都是''0'添加到'C' – tekknolagi 2011-05-01 18:50:03
请打开编译器的警告并修复它报告的内容。当你修改它们时编辑它(例如,如果找不到值,'res'没有在'in_arr'中初始化,''printf(“”,smaller [counter]);'无效) – Mat 2011-05-01 18:50:32