2016-03-03 25 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