バロウズ・ウィーラーが最前線に
-
05-07-2019 - |
質問
私が取り組んでいるプロジェクトでは、O(n)空間にBurrows-WheelerのMoveToFront変換を実装する必要があります。しかし、何らかの理由で、私のコードは私が投げたほとんどの値で動作しますが、すべてではありません。
私の実装は次のようになります:
public byte[] transform (byte[] input)
{
if (input.length == 0)
return input;
IndexedByte[] bytes = new IndexedByte[input.length];
for (int i = 0; i < input.length; i++)
{
bytes[i] = new IndexedByte(input[i],i);
}
for (int i = 0; i < input.length -1; i++)
{
bytes[i].next = bytes[i+1];
}
bytes[input.length - 1].next = bytes[0];
Arrays.sort(bytes);
byte[] newBytes = new byte[input.length];
for (int i = 0; i < bytes.length; i++)
newBytes[i] = bytes[i].b;
int[] indexes = new int[input.length];
for (int i = 0; i < indexes.length; i++)
indexes[i] = (bytes[i].origIndex + (input.length - 1)) % input.length;
int x = 0;
String str = new String(input);
for (int i = 0; i < input.length; i++)
{
if (bytes[i].origIndex == 0)
{
x = i;
break;
}
}
byte[] header = intToByteArray(x);
byte[] result = new byte[indexes.length+header.length];
for (int i = 0; i < header.length; i++)
result[i] = header[i];
for (int i = 0; i < indexes.length; i++)
result[i+header.length] = input[indexes[i]];
return result;
}
ここで私が間違っていることについて何かアドバイスはありますか?英数字以外の文字が検出された場合、これは機能しないようです(つまり、エンコード自体、/ *などが失敗するようです)。
解決
このコードでさまざまなテストを実行した後、正しく動作しているように見えます。発生している問題は、おそらく byteArrayToInt
実装の符号拡張によるものです。たとえば、次のコードは、予想される 128
ではなく、 -128
を出力します。
System.out.println(byteArrayToInt(intToByteArray(128)));
コードを次のように変更してください:
private int byteArrayToInt(byte[] b) {
return (b[0] << 24) +
((b[1] & 0xFF) << 16) +
((b[2] & 0xFF) << 8) +
(b[3] & 0xFF);
}
余談ですが、 IndexedByte.compareTo
内の MAXIMUM = 50000
制限に達することはありません。長さ5214の入力配列を持つ java.lang.StackOverflowError
を取得しました。これを再帰的ではなく反復的に変更することをお勧めします(入力配列の長さを知っているので、これはかなり簡単です)また、入力配列のすべてのバイトが等しい病理学的なケースでの余分なループを防ぎます。
所属していません StackOverflow