Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 需要制作一个非常大的数组[2^16+;1][2^16+;1]-数组大小太大:(_C - Fatal编程技术网

C 需要制作一个非常大的数组[2^16+;1][2^16+;1]-数组大小太大:(

C 需要制作一个非常大的数组[2^16+;1][2^16+;1]-数组大小太大:(,c,C,问候 我需要计算一个由16位单词组成的信号的一阶熵(Markov源,如这里的wiki)。 这意味着,我必须计算a->b(符号b出现在a之后)的每个组合在数据流中发生的频率。 当我只对4个低有效位或4个高有效位执行此操作时,我使用了一个二维数组,其中第一个维度是第一个符号,第二个维度是第二个符号 我的算法是这样的 读取当前符号 数组[上一个符号][当前符号]++ 上一个符号=当前符号 向前移动1个符号 然后,数组[a][b]意味着符号b在符号a之后在流中出现了多少次 现在,我知道C中的数组是一个指

问候

我需要计算一个由16位单词组成的信号的一阶熵(Markov源,如这里的wiki)。 这意味着,我必须计算a->b(符号b出现在a之后)的每个组合在数据流中发生的频率。 当我只对4个低有效位或4个高有效位执行此操作时,我使用了一个二维数组,其中第一个维度是第一个符号,第二个维度是第二个符号

我的算法是这样的

  • 读取当前符号
  • 数组[上一个符号][当前符号]++
  • 上一个符号=当前符号
  • 向前移动1个符号
  • 然后,数组[a][b]意味着符号b在符号a之后在流中出现了多少次

    现在,我知道C中的数组是一个指针,它是递增的以获得精确的值,就像从数组[10][10]中获取元素[3][4]一样,我必须将指向数组[0][0]的指针递增(3*10+4)(数组中存储的变量大小)。我知道问题一定是2^32个unsigned long类型的元素占用的时间太多了

    但是,有没有办法解决这个问题


    或者可能有另一种方法来实现这一点?

    也许您可以对数据进行多次传递。从符号X开始的对的熵贡献基本上与从任何其他符号开始的对无关(当然,除了它们的总数),因此,您可以计算所有这些对的熵,然后丢弃分布数据。最后,将2^16个部分熵值合并得到总数。您不必对数据进行2^16次传递,您可以在一次传递中“感兴趣”尽可能多的初始字符


    或者,如果您的数据小于2^32个样本,那么您肯定不会看到所有可能的对,因此您实际上不需要为每个对分配计数。如果样本足够小,或者熵足够低,那么某种稀疏数组将比完整的16GB矩阵使用更少的内存。

    二维数组包含32'000 x 32'000个元素的整数数组(4字节)占用大约16 GB的RAM。您的机器有那么多内存吗

    无论如何,在超过10亿个数组元素中,只有极少数元素的计数不同于零,所以最好使用某种稀疏存储


    一个解决方案是使用一个字典,其中元组(a,b)是键,出现次数是值。

    在Ubuntu 10.10 x64上做了一个快速测试

    gt@thinkpad-T61p:~/test$ uname -a Linux thinkpad-T61p 2.6.35-25-generic #44-Ubuntu SMP Fri Jan 21 17:40:44 UTC 2011 x86_64 GNU/Linux gt@thinkpad-T61p:~/test$ cat mtest.c #include <stdio.h> #include <stdlib.h> short *big_array; int main(void) { if((big_array = (short *)malloc(4UL*1024*1024*1024*sizeof (short))) == NULL) { perror("malloc"); return 1; } big_array[0]++; big_array[100]++; big_array[1UL*1024*1024*1024]++; big_array[2UL*1024*1024*1024]++; big_array[3UL*1024*1024*1024]++; printf("array[100] = %d\narray[3G] = %d\n", big_array[100], big_array[3UL*1024*1024*1024]); return 0; } gt@thinkpad-T61p:~/test$ gcc -Wall mtest.c -o mtest gt@thinkpad-T61p:~/test$ ./mtest array[100] = 1 array[3G] = 1 gt@thinkpad-T61p:~/test$ gt@thinkpad-T61p:~/test$uname-a Linux thinkpad-T61p 2.6.35-25-generic#44 Ubuntu SMP Fri Jan 21 17:40:44 UTC 2011 x86_64 GNU/Linux gt@thinkpad-T61p:~/test$cat mtest.c #包括 #包括 短*大_数组; 内部主(空) { if((大数组=(短*)malloc(4UL*1024*1024*1024*sizeof(短)))==NULL){ 佩罗尔(“马洛克”); 返回1; } 大_数组[0]++; 大_数组[100]+; 大_阵列[1UL*1024*1024*1024]++; 大_阵列[2UL*1024*1024*1024]++; 大_阵列[3UL*1024*1024*1024]++; printf(“数组[100]=%d\narray[3G]=%d\n”、大数组[100]、大数组[3UL*1024*1024*1024]); 返回0; } gt@thinkpad-T61p:~/test$gcc-墙壁测试c-o测试 gt@thinkpad-T61p:~/test$/mtest 数组[100]=1 阵列[3G]=1 gt@thinkpad-T61p:~/test$ 看起来linux上的虚拟内存系统可以胜任这项工作,只要您有足够的内存和/或交换


    玩得开心!

    数据流中有多少符号?C中的数组不是指针。最简单的解决方案是使用64位平台/OS/编译器,并有足够的内存。我明白了,在这种情况下,字典似乎比数组好得多。只是我从来没有想过这一点,因为程序从4位分析器开始,所以很简单r使用16x16阵列。。