4

除了循环遍历数组的每个元素之外,是否可以仅循环遍历具有赋值的元素?

在下面的示例中,我只想循环遍历三个元素,而不是遍历数组中的每个元素。我有什么选择?我讨厌循环遍历数千个元素,因为它们中只有少数是基于特定逻辑分配的。

main()
{
    int i, intArray[10000];
    intArray[334] = 30;
    intArray[563] = 50;
    intArray[989] = 90;

    for (i = 0; i < 10000; i++)
    {
      printf("%d\n", intArray[i]);
    }
}

感谢您阅读帖子。对不起,如果它是重新发布。我不会在论坛中找到类似的问题。

4

3 回答 3

6

只是间接的:

#include <stdio.h>

int main(void)
{
    int i, intArray[10000];
    int active[10000];
    int n_active = 0;
    intArray[334] = 30;
    active[n_active++] = 334;
    intArray[563] = 50;
    active[n_active++] = 563;
    intArray[989] = 90;
    active[n_active++] = 989;

    for (i = 0; i < n_active; i++)
      printf("%d\n", intArray[active[i]]);
    return 0;
}

或者,更简洁但不是更清楚:

#include <stdio.h>

int main(void)
{
    int i, intArray[10000];
    int active[10000];
    int n_active = 0;
    intArray[active[n_active++]=334] = 30;
    intArray[active[n_active++]=563] = 50;
    intArray[active[n_active++]=989] = 90;

    for (i = 0; i < n_active; i++)
      printf("%d\n", intArray[active[i]]);
    return 0;
}

如果对同一个索引有多个赋值(该索引将在active数组中存储两次),这两个程序都会受到影响。就目前而言,它也不检查active数组是否溢出(但这不应该成为问题;假设只有少数行被填充),并且索引按它们的顺序存储'重新呈现 - 不是按关键顺序。所有这些缺陷都可以修复,但需要更多代码(可能需要一个或两个函数)。

于 2013-09-07T04:18:07.363 回答
1

你可以做这样的事情

# include <stdio.h>
int totalElements = 0;
struct 
{
   int index, data;
} Data[10000];

void addElement(int index, int data)
{
   Data[totalElements].data = data;
   Data[totalElements++].index = index;
}

main()
{
   int i;
   addElement(334, 30);
   addElement(563, 50);
   addElement(989, 90);
   for (i = 0; i < totalElements; i++)
   {
      printf("%d %d\n", Data[i].data, Data[i].index);
   }
}

输出

30 334
50 563
90 989

这也受到 Jonathan Leffler 提到的相同限制。

编辑

# include <stdio.h>
int totalElements = 0;
struct
{
   int index, currentElement = 0, data[100];
} Data[10000];

void addElement(int index, int data)
{
   int i;
   for (i = 0; i < totalElements; i++)
   {
      if (Data[i].index == index)
      {
         Data[i].data[Data[i].currentElement++] = data;
         return;
      }
   }
   Data[totalElements].data[Data[totalElements].currentElement++] = data;
   Data[totalElements++].index = index;
}

main()
{
   int i, j;
   addElement(334, 30);
   addElement(334, 40);
   addElement(563, 50);
   addElement(563, 60);
   addElement(989, 80);
   addElement(989, 90);
   for (i = 0; i < totalElements; i++)
   {
      for (j = 0; j < Data[i].currentElement; j++)
      {
         printf("%d %d\n", Data[i].index, Data[i].data[j]);
      }
   }
}

输出

334 30
334 40
563 50
563 60
989 80
989 90

使用这个想法,您可以克服 Jonathan Leffler 提到的限制。

于 2013-09-07T04:40:15.180 回答
0

也许您可以使用不同的数据结构,例如链表。列表中的每个节点可以有两个int值,一个可以是索引,另一个可以是值。然后,链接列表将仅包含已分配的索引(并且您也可以具有 value==0,如果这与正常的未分配索引有所不同)。

另一种选择是使用类似字典结构的东西。可能有 C 的 Dictionary 实现——不过我想说,如果 C++ 可用,也许你应该改用它(除非你特别想学习或受限于 C)——C++ 有许多开箱即用的数据类型。

于 2013-09-07T04:19:32.807 回答