Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 位数组相等_C#_.net_Equals_Bitarray - Fatal编程技术网

C# 位数组相等

C# 位数组相等,c#,.net,equals,bitarray,C#,.net,Equals,Bitarray,在我的应用程序中,我需要的不仅仅是System.Collections.BitArray类。具体来说,我需要位数组: 不变 使用值语义实现相等 我创建了自己的struct,主要复制了BitArray实现的内部结构。(谢谢 我不是每天都处理逐位运算,所以我对我的平等实现没有最高程度的信心。(它通过了我正在进行的单元测试,但我可能遗漏了一些边缘案例。)我提出的解决方案如下所示。我希望其他人的反馈和回答能更正确、更有效 与CLR位数组一样,长度字段指的是结构中的位数,数组字段(或数组属性)指的是表

在我的应用程序中,我需要的不仅仅是
System.Collections.BitArray
类。具体来说,我需要位数组:

  • 不变
  • 使用值语义实现相等
我创建了自己的
struct
,主要复制了
BitArray
实现的内部结构。(谢谢

我不是每天都处理逐位运算,所以我对我的平等实现没有最高程度的信心。(它通过了我正在进行的单元测试,但我可能遗漏了一些边缘案例。)我提出的解决方案如下所示。我希望其他人的反馈和回答能更正确、更有效

与CLR
位数组
一样,
长度
字段指的是结构中的位数,
数组
字段(或
数组
属性)指的是表示位的32位整数数组

[澄清]我选择在构造函数和其他方法中采用简单的方法,这样我就不能依赖不必要的位为零。比如说,

  • Not()
    通过对整数数组元素进行位求反(
    ~
    )来实现
  • 可以使用一个构造函数,该构造函数采用长度和布尔值来初始化所有位。如果初始化值为true,我将int数组的所有元素设置为-1(以2的补码表示,由所有1表示)
  • 等等
因此,我需要在比较中处理(或者更确切地说,忽略)它们。一个很好的解决方案是始终保持这些位为零,但在我的情况下,这将导致更多的工作(对计算机和我来说!)

相等方法:

public bool Equals(ImmutableBitArray other)
{
    if (this.length != other.length)
    {
        return false;
    }

    for (int i = 0; i < this.Array.Length; i++)
    {
        if (this.Array[i] != other.Array[i])
        {
            // This does not necessarily mean that the relevant bits of the integer arrays are different.
            // Is this before the last element in the integer arrays?
            if (i < this.Array.Length - 1)
            {
                // If so, then the objects are not equal.
                return false;
            }

            // If this is the last element in the array we only need to be concerned about the bits
            // up to the length of the bit array.
            int shift = 0x20 - (this.length % 0x20);
            if (this.Array[i] << shift != other.Array[i] << shift)
            {
                return false;
            }
        }
    }

    return true;
}
public bool Equals(不可变位数组其他)
{
if(this.length!=其他.length)
{
返回false;
}
for(int i=0;i如果(this.Array[i]如果在
ImmutableBitArray
的构造函数中,最后一个元素上未使用的“填充位”被强制归零,则无需跳转到环中,只检查最后一个元素中的有效位,因为在相同的实例中填充将相同

这将很好地简化
Equals()
GetHashCode()
方法:

public bool Equals(ImmutableBitArray other)
{
    if (this.length != other.length)
    {
        return false;
    }

    for (int i = 0; i < this.Array.Length; i++)
    {
        if (this.Array[i] != other.Array[i])
        {
            // since padding bits are forced to zero in the constructor,
            //  we can test those for equality just as well and the valid
            //  bits
            return false;
        }
    }

    return true;
}


public override int GetHashCode()
{
    int hc = this.length;

    for (int i = 0; i < this.Array.Length; i++)
    {
        // since padding bits are forced to zero in the constructor,
        //  we can mix those into the hashcode no problem

        hc ^= this.Array[i];
    }

    return hc;
}
public bool Equals(不可变位数组其他)
{
if(this.length!=其他.length)
{
返回false;
}
for(int i=0;i
更新:我下面的原始分析不正确


不幸的是,经过几个小时的搜索和研究,我对
的行为不正确,我终于得到了我的答案并想与大家分享。我没有回顾性能,因为我只关心可读性

if (input1.length != input2.length)
{
    return false;
}

var result = new BitArray(input1);
result = result.Xor(input2);

if (result.Cast<bool>().Contains(true))
    return false;
return true;
if(input1.length!=input2.length)
{
返回false;
}
var结果=新的位数组(input1);
结果=结果.Xor(输入2);
if(result.Cast()包含(true))
返回false;
返回true;

数组成员的类型是什么?不必特别处理最后一个字节,高位将为零。@nobugz:我创建实例的方式并不总是正确的。(请参阅下面我对Michael Burr的评论;另请参阅
ctor(int,bool)
中的
位数组
;我使用-1做同样的事情。)但这可能是更简单的方法。我认为当位长度是32的倍数时,这里实际上存在一个微妙的错误。有关详细信息,请参阅我的第二个答案(不是对第一个答案的编辑):+1非常好的想法。实际上,我是沿着这条路开始的。但它也使其他一些函数复杂化。例如,执行
not()的最简单方法
就是做
result.Array[i]=~this.Array[i]
对于int数组中的每个元素,这将在零部分中留下1。我必须在某个地方处理多余的元素,在我的情况下,在比较点进行处理是最简单的。是的-我想你必须在某个地方付费。+1非常好!我想知道为什么我在这个场景中的单元测试通过并发现了这一点(至少在C中),n在我的例子中,我允许使用零长度的位数组,因此一些风格上的建议将失败。但很明显,我在我的问题中没有提到这一点,所以你没有办法知道。谢谢你的建议!@Dave:我对我认为的bug的描述是不正确的-C定义了左移位运算符来完成代码所需的操作。我已经在答案的开头添加了一个勘误表…我还考虑了xor运算符。但只有当我们能够以某种方式获得底层字节并与0进行比较,而不是迭代每个位时,这才有用。
(this.Array[i] << shift)
(this.Array[i] << (shift & 0x1f))
int shift = 0x20 - (this.length % 0x20);
if (this.Array[i] << shift != other.Array[i] << shift)
public bool Equals(ImmutableBitArray other)
{
    if (this.length != other.length)
    {
        return false;
    }

    int finalIndex = this.Array.Length - 1;

    for (int i = 0; i < finalIndex; i++)
    {
        if (this.Array[i] != other.Array[i])
        {
            return false;
        }
    }

    // check the last array element, making sure to ignore padding bits

    int shift = 32 - (this.length % 32);
    if (shift == 32) {
        // the last array element has no padding bits - don't shift
        shift = 0;
    }

    if (this.Array[finalIndex] << shift != other.Array[finalIndex] << shift)
    {
        return false;
    }

    return true;
}
if (input1.length != input2.length)
{
    return false;
}

var result = new BitArray(input1);
result = result.Xor(input2);

if (result.Cast<bool>().Contains(true))
    return false;
return true;