的主要問題是在第二次分配索引該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