0

我有一个清单:

id num1 ...
-----------
 1  123 ...
 1  456 ...
 2  789 ...
 2  666 ...

并想基于它创建一个对象数组:

{ 1, [123, 456], [...] },
{ 2, [789, 666], [...] } 

这是我的伪代码:

int previous_id = -1;
array a1 = null; // B
array a2 = null; // B
array a3 = null; // B
array a4 = null; // B
while (++c) { // c is a pointer pointing to the list
  if (c.id != previous_id && previous_id != -1) {
    j[i++].id = previous_id;   // A
    j[i++].data1 = a1;         // A
    j[i++].data2 = a2;         // A
    j[i++].data3 = a3;         // A
    j[i++].data4 = a4;         // A
    a1 = null;   // B
    a2 = null;   // B
    a3 = null;   // B
    a4 = null;   // B
  }
  a1.add(c.num1);
  a2.add(c.num2);
  a3.add(c.num3);
  a4.add(c.num4);
  previous_id = c.id;
}
j[i++].id = previous_id;   // A
j[i++].data1 = a1;         // A
j[i++].data2 = a2;         // A
j[i++].data3 = a3;         // A
j[i++].data4 = a4;         // A

它正在工作,但有一些冗余代码,即 A 和 B

是否可以合并它们以使其更简洁明了?

4

3 回答 3

1

如果这是目标,您可以做几件事来提高代码的清晰度。

与其使用不同的名称,不如使用索引。

“数组”没有定义,所以我猜它是一个表格。你可以有类似的东西:

  #define NB_ARRAYS 4
  array myArrays[NB_ARRAYS];

这样,您将能够遍历您的数组,并最终在将来随时更改数组的数量。

好的想法是您不再需要单独列出您的数组,一个循环就足够了。因此 :

    a1 = null;   // B
    a2 = null;   // B
    a3 = null;   // B
    a4 = null;   // B

变成

    { int i; for (i=0; i<NB_ARRAYS; i++) myArrays[i] = NULL; }

您可能会抱怨这并不比第一个版本好,但您实际上可以将这种复杂性隐藏在宏后面:

    #define INIT_ARRAYS(a) { int i; for (i=0; i<NB_ARRAYS; i++) a[i] = NULL; }

甚至更好,在一个内联函数后面:

    static inline void initArrays(array* a) { int i; for (i=0; i<NB_ARRAYS; i++) a[i] = NULL; }

所以它变成:

    initArrays(myArrays);

这更清楚。

重用相同的原则,它会导致你的代码是这样的:

    int previous_id = -1;
    initArrays(myArrays);

    while (++c) 
    { // c is a pointer pointing to the list
       addToArrays(myArrays, c);
       if (c.id != previous_id && previous_id != -1 || c.islast() ) 
       {
           j[i++].id = previous_id;   // A
           setArrays(j, i, myArrays); i+=NB_ARRAYS;
           if (!c.islast()) { initArrays(myArrays); }
       }
    }
    previous_id = c.id;

这应该更容易阅读,因此更容易维护。

另外:尝试使用更容易阅读的变量。在这个例子中,我不知道 c、i 或 j 代表什么(也不知道它们是在哪里定义的)。使用 5-6 个字符来正确命名它们不会花费太多,并且确实有助于代码维护。

于 2013-10-21T09:35:34.227 回答
0

你的代码对我来说有点太伪代码了——建议很大程度上取决于你的实际实现是什么样的。不过,我会给出一些想法。

对于A部分:

struct's in C 将允许您执行以下操作:

someStruct temp = {previous_id, a1, a2, a3, a4};
j[i++] = temp;

对于B部分:

我假设null实际上指的是一个空数组,而不是一个null数组,并且您可能有一个固定长度的数组,其中包含一个用于填充长度的单独长度指示符。

您始终可以拥有一个长度数组,一个 2D 主数组,以及memset整个长度数组,0而不是一个一个地设置它们。

于 2013-10-21T08:19:13.270 回答
0

刚刚找到了一种合并A和避免重置的方法B

int previous_id = -1;
array a1 = null; // B
array a2 = null; // B
array a3 = null; // B
array a4 = null; // B
while (++c) { // c is a pointer pointing to the list
  a1.add(c.num1);
  a2.add(c.num2);
  a3.add(c.num3);
  a4.add(c.num4);
  if (c.id != previous_id && previous_id != -1
      || c.islast() ) {
    j[i++].id = previous_id;   // A
    j[i++].data1 = a1;         // A
    j[i++].data2 = a2;         // A
    j[i++].data3 = a3;         // A
    j[i++].data4 = a4;         // A
    if (!c.islast()) {
        a1 = null;   // B
        a2 = null;   // B
        a3 = null;   // B
        a4 = null;   // B
    }
  }
  previous_id = c.id;
}
于 2013-10-21T08:56:59.370 回答