【问题标题】:Stream of short[]短流[]
【发布时间】:2016-06-16 20:26:03
【问题描述】:

您好,我需要计算文件的 m 阶熵,其中 m 是位数 (m

所以:

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

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

对于 m = 8 这很容易,因为我考虑的是一个字节。 由于 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 );
    }
}

我假设在这种情况下使用 shorts。 如果我使用字节,我怎样才能为 m > 8 做这样的循环? 该循环不起作用,因为我必须连接多个字节并且每次改变要连接的位数..

有什么想法吗? 谢谢

【问题讨论】:

  • 如果你只是计算一个总和,为什么要把每一个值都保存在一个数组中?
  • 感谢您的回复。我需要将值保存在数组中,因为我需要获取 m 位的所有子序列,然后计算每个序列的概率。

标签: java inputstream entropy datainputstream


【解决方案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]]);

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

然后操作缓冲区。

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

【讨论】:

  • 那我们不明白你的问题。对于 m=9,你得到 1 字节+1 位
  • 这个表达式 (n >> i) & 2^m-1 不清楚,但是你想要每 m 位对吗?
  • 为什么不清楚?是的,这就是我想要的,m 位序列
  • 感谢您的帮助,您的代码给了我这个错误error: incompatible types: possible lossy conversion from int to short
  • Mmh outOfBound exception in line buffer[j]=(short)((byteData[i]&lt;&lt;8)|byteData[i+1])
猜你喜欢
  • 2016-09-17
  • 2012-02-23
  • 2015-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-06
  • 2017-01-20
相关资源
最近更新 更多