【问题标题】:Bitwise operators on different length BitArrays不同长度 BitArrays 上的位运算符
【发布时间】:2014-03-31 04:36:49
【问题描述】:

我有 2 个 BitArray 项目,我需要知道每个项目中是否有任何位相同,“AND”。 但是,BitArrays 的长度可以不同,以太一个可以大于或小于另一个。

如何对两个 BitArray 进行“与”运算,而不会因为大小不同而出现异常? 这会发生很多,所以我需要它相当快。

例子

  int[] ids = new int[3];
  ids[0] = 1;
  ids[1] = 3;
  ids[2] = 5;
  BitArray bs1 = new BitArray(ids.Max()+1);
  for (int i = 0; i < ids.Count(); ++i)
  {
    bs1[ids[i]] = true;
  }


  ids[0] = 1;
  ids[1] = 59;
  ids[2] = 1111;
  BitArray bs2 = new BitArray(ids.Max()+1);
  for (int i = 0; i < ids.Count(); ++i)
  {
    bs2[ids[i]] = true;
  }

  ids[0] = 0;
  ids[1] = 5;
  ids[2] = 33;
  BitArray bs3 = new BitArray(ids.Max()+1);
  for (int i = 0; i < ids.Count(); ++i)
  {
    bs3[ids[i]] = true;
  }


  //if bs1 AND bs2 bitcount > 0 DisplayMessage("1 and 2 has some same items")
  //if bs1 AND bs3 bitcount > 0 DisplayMessage("1 and 3 has some same items")
  //if bs2 AND bs3 bitcount > 0 DisplayMessage("2 and 3 has some same items")

为了解决我的问题,我修改了 BitArray 代码并添加了以下内容

public static MyBitArray TruncateCopy(MyBitArray source, int size)
{
  MyBitArray dest = new MyBitArray(size);

  //copy all the arrays
  for (int i = 0; i < dest.m_array.Length; ++i)
  {
    dest.m_array[i] = source.m_array[i];
  }

  //remove any of the items over the given size
  for (int i = ((size % 32) + 1); i < 32; ++i)
  {
    dest.m_array[i >> 5] &= ~(1 << (i & 31));
  }

  return dest;
}

public bool HasCommonBits(MyBitArray comp)
{
  MyBitArray copied, other;

  if (this.Length < comp.Length)
  {
    other = this;
    copied = TruncateCopy(comp, this.Length);
  }
  else
  {
    copied = TruncateCopy(this, comp.Length);
    other = comp;
  }

  MyBitArray compareEq = copied.And(other);

  return (!compareEq.IsEmpty());
}

public bool IsEmpty()
{
  for (int i = 0; i < this.m_array.Length; ++i)
  {
    if (m_array[i] != 0)
      return false;
  }

  return true;
}

public bool IsFull()
{
  //run through all the full sets
  for (int i = 0; i < this.m_array.Length - 1; ++i)
  {
    if (m_array[i] != -1) //-1 is all bits set in an integer
      return false;
  }

  //go through the partial one
  for (int i = 0; i < (this.Length % 32); ++i)
  {
    if (!this[i])
      return false;
  }

  return true;
}

}

【问题讨论】:

  • 如果它们是不同的长度,你需要首先弄清楚如何使它们相同,即是否删除最高或最低有效(或其他?)位。
  • 如果它们的长度不同,那么在较长的那个中就不可能有任何匹配的位。因此我们可以忽略更长的 BitArray 中的额外数据。

标签: c# bitwise-operators bitarray


【解决方案1】:

根据此评论完全修改:

您的示例的结果位数组将是 01010。我最初的问题是我需要查看是否有任何位相同。因此,具有任何 1 的结果位数组将为 True,所有 0 将为 False

BitArrray truncateCopyBA(BitArray source, int size)
{
    BitArray dest = new BitArray(size);

    for(int i = 0; i < size; ++i)
    {
        dest[i] = source[i];
    }

    return dest;
}

bool YourFunc(BitArray a, BitArray b)
{
    BitArray one, two;

    if (a.Length < b.Length)
    {
        one = a;
        two = truncateCopyBA(b, a.Length);
    }
    else
    {
        one = truncateCopyBA(a, b.Length);
        two = b;

        // If you want to see which bits in both arrays are both ones, then use .And()
        // If you want to see which bits in both arrays are the same, use .Not(.Xor()).
        BitArray compareEq = a.And(b);
        bool anyBitsSame=false;
        for(int i = 0; i < compareEq.Length; ++i)
        {
            if(compareEq.Get(i))
            {
                return true;
            }
        }

        return false
    }
}

我相信这就是您要寻找的东西,但老实说,经过澄清后,您的问题仍然很模糊。

【讨论】:

  • BitArray.And 返回BitArray,而不是bool
  • @PrestonGuillot 哎呀,我的脑残......将在一秒钟内纠正
  • @PrestonGuillot 感谢您的注意 - 我相信更正的版本现在应该可以做到(尽管不是那么紧凑)
  • 这没有帮助。如果它们的长度不同,我仍然需要结果。
  • @runfastman 然后请用案例示例澄清您的问题并在每个案例中产生结果......即如何将一组 5 位与一组 15 位进行比较 - 高级逻辑......然后我们可以在算法方面提供帮助。
【解决方案2】:

首先,定义在不同长度的情况下要发生的情况。也许您只是想比较第一个 Math.Min(len1, len2) 元素。在这种情况下,编写一个for 循环,其索引变量的范围从0 到Math.Min(len1, len2)。比较循环体中的各个数组元素。

我用反射器检查了BitArray没有办法对其进行修整,或执行部分And。你在这门课上不走运。将其替换为支持您需要的自定义编写的类。写一个位数组并不是特别难。

【讨论】:

  • 我不想使用循环,BitArray 的整个点是一个非常快速的检查。我需要一种方法来从较长的 BitArray 中提取额外信息并执行 bitwize "AND"
  • 好的,我明白了。我用反射器检查了BitArray。没有办法修剪它,或执行部分And。你在这门课上不走运。将其替换为支持您需要的自定义编写的类。写一个位数组并不是特别难。
  • 我能用 0 快速加长较短的那个吗?那也行。
  • 大小是固定的,唉。您可以使用 Reflector 查看所有可用的内容。请注意,自定义的 BitArray 不会比内置的慢。它甚至可以更快。
  • 是的,定制一个会很好,但我对 c# 还很陌生,我需要很长时间才能弄清楚所有的部分。大多数其他语言都有很好的位集库,为什么c#没有,似乎我什至无法快速检查是否所有位都是1或0而没有循环。
猜你喜欢
  • 2011-05-18
  • 1970-01-01
  • 1970-01-01
  • 2016-04-05
  • 2012-04-03
  • 2014-03-09
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多