2016-03-03 67 views
-2

您好,我需要计算文件的阶m的熵,其中m是位数(m < = 16)。Stream of short []

所以:

H_m(X)= - sum_i = 0到i = 2^m-1个{(P_I,M)(log_2(P_I,M))}

所以,我想创建一个输入流来读取文件,然后计算每个由m位组成的序列的概率。

对于m = 8,这很容易,因为我考虑了一个字节。 由于这个m < = 16我试图考虑为原始类型short,将short的每个short存储在数组short []中,然后使用按位运算符处理位以获取文件中所有m位的序列。 这是个好主意吗?

无论如何,我无法创建一个短的流。这是我所做的:

public static void main(String[] args) { 
    readFile(FILE_NAME_INPUT); 
} 

public static void readFile(String filename) { 
    short[] buffer = null; 
    File a_file = new File(filename); 
    try { 
     File file = new File(filename); 

     FileInputStream fis = new FileInputStream(filename); 
     DataInputStream dis = new DataInputStream(fis); 

     int length = (int)file.length()/2; 
     buffer = new short[length]; 

     int count = 0; 
     while(dis.available() > 0 && count < length) { 
      buffer[count] = dis.readShort(); 
      count++; 
     } 
     System.out.println("length=" + length); 
     System.out.println("count=" + count); 


     for(int i = 0; i < buffer.length; i++) { 
      System.out.println("buffer[" + i + "]: " + buffer[i]); 
     } 

     fis.close(); 
    } 
    catch(EOFException eof) { 
     System.out.println("EOFException: " + eof); 
    } 
    catch(FileNotFoundException fe) { 
     System.out.println("FileNotFoundException: " + fe); 
    } 
    catch(IOException ioe) { 
     System.out.println("IOException: " + ioe); 
    } 
} 

但我失去了一个字节,我不认为这是程序的最佳途径。


这是我想使用位运算符的事:

int[] list = new int[l]; 
foreach n in buffer { 
    for(int i = 16 - m; i > 0; i-m) { 
     list.add((n >> i) & 2^m-1); 
    } 
} 

我假设在这种情况下使用短裤。 如果我使用字节,我怎么能做一个类似于m> 8的循环? 该周期不起作用,因为我必须连接多个字节,并且每次都要改变要连接的位数。

任何想法? 感谢

+0

如果您只是计算总和,为什么要将每个值保存在一个数组中? – VGR

+0

感谢您的回复。我需要将值保存在数组中,因为我需要获取m位的所有子序列,然后计算每个序列的概率。 – lon

回答

1

我认为你需要有一个字节数组:

public static void readFile(String filename) { 
    ByteArrayOutputStream outputStream=new ByteArrayOutputStream(); 
    try { 
    FileInputStream fis = new FileInputStream(filename); 
    byte b=0; 
    while((b=fis.read())!=-1) { 
     outputStream.write(b); 
    } 
    byte[] byteData=outputStream.toByteArray(); 
    fis.close(); 
    } 
    catch(IOException ioe) { 
    System.out.println("IOException: " + ioe); 
} 

然后,你可以操纵byteData按您的位操作。

-

如果你想与短裤上班,你可以结合读取字节这样

short[] buffer=new short[(int)(byteData.length/2.)+1]; 
j=0; 
for(i=0; i<byteData.length-1; i+=2) { 
    buffer[j]=(short)((byteData[i]<<8)|byteData[i+1]); 
    j++; 
} 

要检查单字节做到这一点

if((byteData.length%2)==1) last=(short)((0x00<<8)|byteData[byteData.length-1]]); 

最后是一个短,它可以放在缓冲区[buffer.length-1];我不确定缓冲区中的最后位置是否可用或占用;我认为这是,但你需要退出循环后检查j;如果j的值是buffer.length-1,那么它是可用的;否则可能会有一些问题。

然后操纵缓冲区。

第二种使用字节的方法涉及更多。这是它自己的问题。所以试试以上。

+0

对于m <= 8,你说得对,但对于m> 8没有... – lon

+0

我们不明白你的问题。对于m = 9,你得到1个字节+ 1位 – gpasch

+0

我编辑了我的问题并添加了一些细节。 – lon