高效的数组索引

时间:2011-04-09 18:53:26

标签: c

假设我有

z[7]={0, 0, 2, 0, 1, 2, 1}

这意味着 - 在第0组,第二组0,第三组2等中分配的第一次观察 我想写一个有效的代码来获得3X的数组?这样,在第一行中,我在第一组中分配了所有观察结果,在第二组中分配了所有在第二组中分配的所有观察结果等等。

0, 1, 3
4, 6 
2, 5

这必须是一般的,也许我可以

z={0, 0, 2, 0, 1, 2, 1, 3, 4, 2, 0, 4, 5, 5, 6, 7, 0}

因此列数未知

我确实完成了我的作业,并且代码附在此消息上,但必须有更好的方法来完成。我相信指针,但我真的不知道如何。

#include <stdio.h>
int main(){
  int z[7]={0, 0, 2, 0, 1, 2, 1}, nj[3], iz[3][7], ip[3], i, j;


for(j=0; j<3; j++){
    ip[j] = 0;
    nj[j] = 0;
  }

  for(i=0; i <7; i++ ){
    nj[z[i]] = nj[z[i]] + 1;
    iz[z[i]][ip[z[i]]] = i;
    ip[z[i]] = ip[z[i]] + 1;    
  }  

  for(j=0; j<3 ;j++){
    for(i=0; i < nj[j]; i++){
      printf("%d\t", iz[j][i]);
    }
    printf("\n");    
  }
  return 0;  
}

1 个答案:

答案 0 :(得分:1)

这似乎你有两个任务。

  1. 计算z中每个索引的出现次数,并分配正确大小和配置的数据结构。
  2. 迭代数据并将其复制到正确的位置。
  3. 此刻,你似乎通过分配一个大的二维数组iz来天真地解决了(1)。如果您事先知道它的大小限制(并且您的机器将有足够的内存),那么这种方法很好,直到以后才需要修复它。

    我不清楚应该如何处理(2)。当前进入iz的数据是否保证包含[0,1,... n]?


    如果您事先知道iz大小的限制,那么您将必须分配动态结构。我建议使用一个参差不齐的数组,但这意味着两次(甚至三次)传递z

    一个参差不齐的数组是什么意思?像argv的{​​{1}}参数之类的对象,但在这种情况下类型为main。在内存中它看起来像这样:

    int **

    可以使用+----+ +---+ +---+---+---+-- | iz |---->| |---->| | | ... +----+ +---+ +---+---+---+-- | |-- +---+ \ +---+---+---+-- | . | --->| | | ... . +---+---+---+-- . 访问一个参差不齐的数组,就像它是一个二维数组(但它是一种不同类型的对象),这很适合您的目的,因为您可以使用代码调整算法你现在有了,然后拍了其中一个。


    如何设置。

    1. 迭代iz[][]以找到最大的数字z

    2. 分配大小为maxZ的{​​{1}}数组:int*

      我之所以选择maxZ+1,是因为它会将所有指针iz=callac(maxZ+1,sizeof(int*));归为零,但您可以使用calloc并自行将其设为NULL。使数组太大会给我们一个NULL终止,这可能会在以后有用。

    3. 分配大小为NULL的计数器数组:malloc

    4. 迭代maxZ,填写int *cz = calloc(maxZ,sizeof(int));每行所需的条目数。

    5. 对于每一行,分配一个整数数组:z

    6. 最后一次迭代cz,将数字粘贴到for(i=0; i<maxZ; ++i){ iz[i] = malloc(sizeof(int)*cz[i]; },就像你已经做的那样。此时可以重新使用z来跟踪已经在每行中放入了多少个数字,但是您可能希望为此目的分配一个单独的数组,因为这样你有一个记录,每个分配的数组有多大。

    7. 注意:每次拨打izcz时都应附上一张支票,以确保分配有效。我把它作为学生的练习。


      通过使用动态数组可以完全避免对malloc业务的重复传递,但我怀疑你不需要它,也不希望增加复杂性。