【问题标题】:Replace bit in BitArray c#替换BitArray c#中的位
【发布时间】:2016-11-27 07:59:35
【问题描述】:

我正在使用它来将文件转换为 BitArray:

public static byte[] GetBinaryFile(string filename)
{
    byte[] bytes;
    using (FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read))
    {
       bytes = new byte[file.Length];
       file.Read(bytes, 0, (int)file.Length);
    }
    return bytes;
}
var x=GetBinaryFile(@"path");
BitArray bits = new BitArray(x);

如何替换 BitArray 中的 Bit 模式?

【问题讨论】:

  • 你能举个例子吗?
  • 假设我有这个模式:010101,我想用X改变它
  • 你的意思是替换这个模式出现在数组中的任何地方吗?
  • 是的,太好了!
  • 例如,我开始读取并创建 10 位的块,然后如果此模式在这些块中,则替换为 X

标签: c# bitarray


【解决方案1】:

下面的代码应该可以工作,使用基本的两遍算法来查找匹配位置,然后进行替换。

请注意,对于 10MB 的文件,在我的笔记本电脑上大约需要 10 秒。如果你想让它跑得更快,你可以使用字节数组和掩码来实现它,而不是笨拙且不那么强大的 BitArray 抽象。

更好的是,您可以使用不安全的代码,在那里您可以使用指针和更快的复制...但是由于这是一个 C# 问题并且您已经在使用 BitArray 抽象,我想我会告诉您如何可以按原样实现。

    private static BitArray Replace(BitArray input, BitArray pattern, BitArray replacement)
    {
        var replacementPositions = GetReplacementPositions(input, pattern);
        return PerformReplacements(input, pattern.Length, replacement, replacementPositions);
    }

    private static List<int> GetReplacementPositions(BitArray input, BitArray pattern)
    {
        if (pattern.Length == 0) throw new Exception("Pattern cannot have 0 length");

        var matchIndicies = new List<int>();
        var maxCheckIndex = input.Length - pattern.Length;
        var i = 0;
        while (i <= maxCheckIndex)
        {
            if (MatchesAt(input, pattern, i))
            {
                matchIndicies.Add(i);
                i += pattern.Length;
                continue;
            }
            i++;
        }
        return matchIndicies;
    }

    private static bool MatchesAt(BitArray input, BitArray pattern, int index)
    {
        for (var j = 0; j < pattern.Length; j++)
        {
            if (input[index + j] != pattern[j]) return false;
        }
        return true;
    }

    private static BitArray PerformReplacements(BitArray input, int patternLength, BitArray replacement, List<int> replacementPositions)
    {
        var outLength = input.Length + replacementPositions.Count * (replacement.Length - patternLength);
        var output = new BitArray(outLength);

        var currentReadIndex = 0;
        var currentWriteIndex = 0;
        foreach (var matchPosition in replacementPositions)
        {
            var inputSubstringLength = matchPosition - currentReadIndex;

            CopyFromTo(input, output, currentReadIndex, inputSubstringLength, currentWriteIndex);

            currentReadIndex = matchPosition + patternLength;
            currentWriteIndex += inputSubstringLength;

            CopyFromTo(replacement, output, 0, replacement.Length, currentWriteIndex);
            currentWriteIndex += replacement.Length;
        }
        CopyFromTo(input, output, currentReadIndex, input.Length - currentReadIndex, currentWriteIndex);
        return output;
    }

    private static void CopyFromTo(BitArray from, BitArray to, int fromIndex, int fromLength, int toIndex)
    {
        for (var i = 0; i < fromLength; i++)
        {
            to.Set(toIndex + i, from.Get(fromIndex + i));
        }
    }

【讨论】:

  • @Ben 你用 byte[] 制作了一个 BitArray,不是吗?所以你不需要:BitArray value = new BitArray(new [] {xh})
【解决方案2】:

您可以使用 Set 方法在 BitArray 中设置特殊位。

bits.Set(index, value); 

value 是一个布尔值,它将在您的位数组中转换为 0 和 1

即:要将第 10 位设置为 1,请使用

bits.Set(9, true);

【讨论】:

  • @DavidE 对不起,我不明白你在问什么。我不是为使用替换方法而写的。 Set 方法有 2 个输入,第一个是位数组中的索引。所以如果他想把第10位改成1,就得写bits.Set(9, true);
猜你喜欢
  • 2017-05-31
  • 2011-11-16
  • 2016-02-21
  • 2016-10-31
  • 2013-12-26
  • 2014-01-05
  • 2012-06-27
  • 2012-05-30
相关资源
最近更新 更多