用不同大小的位集替换所有内部位集

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用不同大小的位集替换所有内部位集相关的知识,希望对你有一定的参考价值。

我目前正在处理一个二进制文件,稍后将写入另一个二进制文件。这非常重要,这也是我对使用ArrayLists和其他列表犹豫不决的原因,因为它们在尝试直接将其写入文件时往往不能很好地发挥作用。

我从这个二进制文件中检索了字节,并使用BitSet将它们分成多个位。我想我已经找到了如何找到我要替换的bitset。目前看起来有点像这样:

try {
                InputStream inputStream = new FileInputStream(filepath);
                OutputStream outputStream = new FileOutputStream("output.bin");
                byte[] buffer = new byte[4096];
                BitSet bitSet = new BitSet(4096 * 8);
                BitSet bitString = new BitSet(search.length());
                BitSet bitReplace = new BitSet(replace.length());
                // Search String to bitset
                for (int i = search.length() - 1; i >= 0; i--) {
                    if (search.charAt(i) == '1') {
                        bitString.set(search.length() - i - 1);
                    }
                }
                // Replace String to bitset
                for (int i = replace.length() - 1; i >= 0; i--) {
                    if (replace.charAt(i) == '1') {
                        bitReplace.set(replace.length() - i - 1);
                        }
                }
                while (inputStream.read(buffer) != -1) {
                    bitSet = BitSet.valueOf(buffer);
                    bufferCount++;
                    // GET 4096 BYTES AT THE SAME TIME
                    // TURN THEM INTO BITS, WE END UP WITH 4096*8 bits
                    // COMPARE EVERY SEARCHSIZE BITS
                    for (int i = 0; i < bitSet.length(); i++) { 
                        if (bitSet.get(i, i + bitString.length()).equals(bitString)) {
                            //TODO: Replace bitset with a different bit set
                        }
                    }
                }
                inputStream.close();
                outputStream.close();

            } catch (IOException e) {
                System.out.println("IOException");
                System.exit(1);
            }

我所遗漏的是,一旦找到具有不同位集的位模式(可能具有不同大小),如何设置现有位集。

所以说明一下:

发现:01010替换为:001111

会改变这个比特序列:

00|01010|01000000000000010

成:

00|001111|010000000000000010

抽象地,我想到了一个解决方案,就像这样:

1. Find the pattern that matches the SEARCHed pattern
2. Replace a bitset with a completely different bitset(this is what I'm struggling with, I was thinking about just appending everything to the end of the file, but that would not be very efficient in terms of read/write 
3. Shift the other bits to the left or to the right based on the difference between the sizes of the searched pattern and the pattern we're replacing with.
4. Write into file. 
答案

你可以定义一个函数setBitsFromIndex(int i, BitSet source, BitSet dest)

private static void setBitsFromIndex(int i, BitSet source, BitSet dest) {
    for (int j = 0; j < source.length(); j++) {
        dest.set(i+j, source.get(j));
    }
}

然后,在您的代码中:

for (int i = 0; i < bitSet.length() - bitString.length(); i++) { 
    if (bitSet.get(i, i + bitString.length()).equals(bitString)) {

        //Replace bitset with a different bit set

        BitSet tempBitSet = bitSet.get(i + bitString.length(), bitSet.length());
        setBitsFromIndex(i, bitReplace, bitSet);
        setBitsFromIndex(i + bitReplace.length(), tempBitSet, bitSet);

        // if bitReplace is shorter than bitString, we may need to clear trailing bits
        if (bitReplace.length() < bitString.length()) {
            bitSet.clear(i + bitReplace.length() + tempBitSet.length(), bitSet.length());
        }
        break;
    }
}

警告:BitSet的长度不是它的容量,甚至是上一次设置位之前的长度。它是HIGHEST SET(1)BIT的索引+ 1,所以你的bitReplacebitStringbitSet BitSets可能不是你认为它们在最高有效位中有0的长度。如果要包含前导零,则必须单独跟踪bitReplacebitString BitSet的所需大小。

以上是关于用不同大小的位集替换所有内部位集的主要内容,如果未能解决你的问题,请参考以下文章

生成大小为 1 到 n 的所有组合(位集)

在 C++ 中定义一个大的位集

在 SSE 中使用位集的实现和性能

2022-04-24:位集 Bitset 是一种能以紧凑形式存储位的数据结构。 请你实现 Bitset 类。 Bitset(int size) 用 size 个位初始化 Bitset ,所有位都是 0

在初始化时定义位集大小?

比较位集的最快方法(位集上的 < 运算符)?