2011-05-01 43 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中的元素数量。

[编辑]嗯,我想这是一个很值得什么约尔在说什么,我也没有看过很好的第一次[/编辑]