C# 中 BigInteger 的按位运算符 获取下一个子集 (long)获取所有子集 (long)获取下一个子集 (BigInteger)获取所有子集 (BigInteger)从 k 个对象的集合中选择 n 个对象背后的数学long 版本有效但 BigInteger 版本无效的示例

问题描述

问题

我正在尝试使用 BigInteger 值在 C# 中实现 the following Java function,以便 64 位限制不再适用。作为完整性检查,我也将使用 long 的原始函数转换为 C# 代码。然而,问题是,虽然使用 long 的版本有效,但使用 BigInteger 的版本并不总是返回相同的结果。

实施

在 C# 中实现原始函数。

获取下一个子集 (long)

public static long GetNextSubset(long subset)
{
    long smallest = subset& -subset;
    long ripple = subset + smallest;
    long ones = subset ^ ripple;
    ones = (ones >> 2) / smallest;
    subset = ripple | ones;
    return subset;
}

获取所有子集 (long)

我打算使用它们,而不是像在原始 Java 代码中那样打印所有值,因此我单独返回每个值。

public static IEnumerable<long> GetAllSubsets(int n,int k)
{
    long max = 1L << n;
    long subset = (1L << k) - 1L;
    while ((max & subset) == 0)
    {
        yield return subset;
        subset = GetNextSubset(subset);
    }
}

获取下一个子集 (BigInteger)

public static BigInteger GetNextSubsetsBigInt(BigInteger subset)
{
    var smallest = subset& -subset;
    var ripple = subset + smallest;
    var ones = subset ^ ripple;
    ones = (ones >> 2) / smallest;
    subset = ripple | ones;
    return subset;
}

获取所有子集 (BigInteger)

public static IEnumerable<BigInteger> GetAllSubsetsBigInt(int n,int k)
{
    var max = new BigInteger(1 << n);
    var subset = new BigInteger((1 << k) - 1);
    while ((max & subset) == 0)
    {
        yield return subset;
        subset = GetNextSubsetsBigInt(subset);
    }
}

预期值

k 个对象的集合中选择 n 个对象背后的数学

combinatorics 开始,使用选择函数很容易验证生成的数字集合是否具有正确数量的值:

Choose(n,k) = n! / (k! * (n - k)!)

long 版本有效但 BigInteger 版本无效的示例

从一副标准的 52 张扑克牌中抽取两张牌的方法数是 1326,但 BigInteger 实现只产生 190。

如何更正 BigInteger 实现?

解决方法

问题是您在创建 int 之前对 BigInteger 进行了位移。只需更改它以创建一个 BigInteger 值 1,然后进行位移。您甚至可以使用名为 BigInteger.One 的静态属性。

public static IEnumerable<BigInteger> GetAllSubsetsBigInt(int n,int k)
{
    var max = BigInteger.One << n;
    var subset = (BigInteger.One << k) - 1;
    while ((max & subset) == 0)
    {
        yield return subset;
        subset = GetNextSubsetsBigInt(subset);
    }
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...