C# 替换位数组c中的位#

C# 替换位数组c中的位#,c#,bitarray,C#,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, (in

我正在使用它将文件转换为位数组:

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);

如何替换位数组中的位模式

您可以使用Set方法设置位数组中的特殊位

bits.Set(index, value); 
值是一个布尔值,它将在位数组中转换为0和1

i、 e:要将第10位设置为1,请使用

bits.Set(9, true);

可以使用Set方法设置位数组中的特殊位

bits.Set(index, value); 
值是一个布尔值,它将在位数组中转换为0和1

i、 e:要将第10位设置为1,请使用

bits.Set(9, true);

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

请注意,对于10MB的文件,在我的半像样的笔记本电脑上大约需要10秒钟。如果您想让它运行得更快,可以使用字节数组和掩码来实现它,而不是笨重且功能不太强大的位数组抽象

更好的是,你可以使用不安全的代码,在那里你可以使用指针和更快的复制。。。但由于这是一个C#问题,而且您已经在使用位数组抽象,我想我会向您展示如何实现它

    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));
        }
    }
私有静态位数组替换(位数组输入、位数组模式、位数组替换)
{
var replacementPositions=GetReplacementPositions(输入,模式);
返回性能替换(输入、模式、长度、替换、替换位置);
}
私有静态列表GetReplacementPositions(位数组输入,位数组模式)
{
if(pattern.Length==0)抛出新异常(“pattern不能有0长度”);
var matchIndicies=新列表();
var maxCheckIndex=input.Length-pattern.Length;
var i=0;

而(i下面的代码应该可以工作,使用一个基本的两遍算法找到匹配的位置,然后进行替换

请注意,对于10MB的文件,在我的半正派笔记本电脑上大约需要10秒钟。如果你想让它运行得更快,你可以使用字节数组和掩码来实现它,而不是使用笨重且功能不太强大的位数组抽象

更好的是,你可以使用不安全的代码,在那里你可以使用指针和更快的复制…但由于这是一个C#问题,而且你已经在使用位数组抽象,我想我会告诉你如何实现它

    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));
        }
    }
私有静态位数组替换(位数组输入、位数组模式、位数组替换)
{
var replacementPositions=GetReplacementPositions(输入,模式);
返回性能替换(输入、模式、长度、替换、替换位置);
}
私有静态列表GetReplacementPositions(位数组输入,位数组模式)
{
if(pattern.Length==0)抛出新异常(“pattern不能有0长度”);
var matchIndicies=新列表();
var maxCheckIndex=input.Length-pattern.Length;
var i=0;

虽然(你能举个例子吗?假设我有一个模式:
010101
,我想用
X
来改变它,你的意思是在数组中出现的任何地方替换这个模式吗?是的,那太好了!例如,我开始读取和创建10位的块,然后如果这个模式在这些块中,你能举个例子吗?让我们来看看假设我有这个模式:
010101
我想用
X
来改变它,你的意思是在数组中出现的任何地方替换这个模式吗?是的,那太好了!例如,我开始读取和创建10位的块,然后如果这个模式在这些块中,用X@DavidE对不起,我不明白你在问什么,我没有使用替换方法写入。Set方法有2个输入,第一个是位数组中的索引。因此,如果他想将第10位更改为1,他必须写入位。Set(9,true);@DavidE抱歉,我不明白你在问什么。我不是为使用替换方法而写的。Set方法有两个输入,第一个是位数组中的索引。因此,如果他想将第10位更改为1,他必须写入位。Set(9,true);@Ben你从字节[]生成位数组,否?那么你不需要:
BitArray value=new BitArray吗(new[]{xh})
?@Ben您可以从字节[]生成一个位数组,否?因此您不需要:
位数组值=新位数组(new[]{xh})