如何计算给定长度的所有可能二进制子字符串的数量?

时间:2015-10-27 12:05:29

标签: java arrays performance memory out-of-memory

在下面的代码中,我试图在二进制数组中计算长度为m的所有可能的二进制子字符串,这意味着在给定的二进制数组中可以找到2 ^ m个可能的子字符串。

我尝试使用以下方法完成任务:

byte [] E = {0,1,0,0,1,1,0,1,0,1,0,1}; 
int m=3;
int [] c = new int [(int)Math.pow(2,m)];

for(int i=0;i<n;i++)
{
int g=0;
for(int j=0;j<m;j++)
{
g <<= 1;
if(E[i+j]==1)
g++;
}
c[g]++;  
}
for(int i=0;i<c.length;i++)
System.out.print("n("+i+")->"+c[i]+"     ");

输出:

n(0)->0     n(1)->1     n(2)->3     n(3)->1     n(4)->1     n(5)->3     n(6)->1     n(7)->0

上述方法需要将2 ^ m内存分配给数组&#39; c&#39;这将为m的较大值(比如m = 30)生成 OutOfMemoryError

我的问题:

1.有没有更好的方法来避免这种错误,因为m的值可能非常大并且可能不允许内存分配?

2.如果在实际分配之前可以对阵列进行内存分配,我如何准确测试, 我已经尝试过使用

if (Runtime.getRuntime().freeMemory() < ((Integer.SIZE/8)* Math.pow(2, m))) throw new Exception("value of m too large");

检查可用内存,但是当m在21和25之间时,它会抛出异常,而实际分配发生在m <1的情况下(不使用上述测试条件)。 25。

我的方法是否正确?

2 个答案:

答案 0 :(得分:1)

您可以使用字典而不是数组,并懒惰地分配条目。虽然每个条目的开销会大很多,但是你会有少于2个 m 条目,特别是当m变大时,因为只有n-m+1个子串长度{{ 1}}长度为m的字符串。因此,您可能有n个条目(即使是中等n-m+1也比2 m 好得多),但只有当E具有特殊结构时,通常会有更少的条目。

答案 1 :(得分:0)

听起来你问的是数学发布的另一个问题

如果你试图从大小为6(B)的数组中得到大小为3(A)的连续部分,那么你可能得到4个子串(B - A + 1)

主阵列

BBBBBB

子数组

AAABBB

BAAABB

BBAAAB

BBBAAA