2011-05-01 40 views
1

爲什麼我不能使用加入?它沒有從集合B中獲得4(e)...爲什麼?C - 加入陣列

 
#include <stdio.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; 

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"); 
} 

int in_arr(int A, set B[], int B_size) { 
    int res = 0; 
    int counter; 
    for (counter = 0; counter < B_size; counter++) { 
     if (A == B[counter]) { 
      res = 1; 
      break; 
     } 
    } 
    return res; 
} 

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)) { 
      continue; 
     } 
     else { 
      res = 0; 
      break; 
     } 
    } 
    return res; 
} 

int size_c(set arr1[], int arr1_size, set arr2[], int arr2_size) { 
    int i; 
    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++; 
    printf("\nSIZE OF C: %d\n", newsize); 
    return newsize; 
} 

int Join(set arr1[], int arr1_size, set arr2[], int arr2_size, set arr3[], int arr3_size) { 
    int i, j; 
    for (i = 0; i < arr1_size; i++) { 
     arr3[i] = arr1[i]; 
    } 
    for (i = 0; i < arr2_size; i++) { 
     j = i+arr2_size; 
     if (!in_arr(arr2[i], arr3, arr3_size)) { 
      arr3[j] = arr2[i]; 
     } 
    } 
} 

int main() { 
    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); 
    int counter; 
    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"); 
} 
+1

並沒有進一步看起來比'in_arr'。你錯過了'res'的初始化。 – pmg 2011-05-01 18:48:48

+0

好吧我添加了初始化,已編譯,並且所有更改都是''0'添加到'C' – tekknolagi 2011-05-01 18:50:03

+1

請打開編譯器的警告並修復它報告的內容。當你修改它們時編輯它(例如,如果找不到值,'res'沒有在'in_arr'中初始化,''printf(「」,smaller [counter]);'無效) – Mat 2011-05-01 18:50:32

回答

2

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

您的問題是,你正在使用我放置新元素到數組3和訪問來自陣列2的元素創建一個新的變量說j爲用於從數組訪問元素3.

這對我有效。

int Join(set arr1[], int arr1_size, set arr2[], int arr2_size, set arr3[], int arr3_size) { 
    int i; 
    int j = 0; /*NEW VARIABLE*/ 
    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[j+arr1_size] = arr2[i]; /*USE j TO ADD ELEMENT TO arr3*/ 
     j++; /*INCREMENT EACH TIME THIS IS DONE*/ 
     } 
    } 
}
+0

非常感謝你! – tekknolagi 2011-05-01 19:03:18

0

讓我們通過代碼在其中加入嘗試,但e到工會的點運行:

for (i = 0; i < arr2_size; i++) { 
    if (!in_arr(arr2[i], arr3, arr3_size)) { 
     arr3[i+arr1_size] = arr2[i]; 
    } 
} 

在這種情況下,earr2該指數等於4。這不是在arr3,所以我們試圖把它放在arr3的位置i+arr1_size。這裏的問題 - i+arr1_size爲6 + 4,或10 size_c看上去是正確的,所以arr3_size應該是7。( - >圖7是小於10)

因此,代碼認識到e不在arr3還沒有,而它試圖把它放在arr3,但它在這方面失敗,因爲它試圖放置e的索引超出了數組的邊界。

您必須分開記錄arr3中的元素數量。

[編輯]嗯,我想這是一個很值得什麼約爾在說什麼,我也沒有看過很好的第一次[/編輯]