有人能解释一下这个算法是如何检查它是否是一个泛数字的吗?

本文关键字:一个 是否是 检查 数字 能解释 一下 算法 何检查 | 更新日期: 2023-09-27 18:16:37

我知道<<操作数将操作数左边的值与右边的值进行位移位。所以1 <<2等于4。如果一个位存在于值中,则操作数将复制该位。但是我就是无法理解这些代码。

   private static bool isPandigital(long n)
    {
        int digits = 0;
        int count = 0;
        int tmp;
        while (n > 0)
        {
            tmp = digits;
            digits = digits | 1 << (int)((n % 10) - 1);
            if (tmp == digits)
            {
                return false;
            }
            count++;
            n /= 10;
        }
        return digits == (1 << count) - 1;
    }

为什么说1 <<在第8行?为什么模是- 1?最重要的是,我不知道最后一行返回值时发生了什么。非常感谢您的帮助。非常感谢!

有人能解释一下这个算法是如何检查它是否是一个泛数字的吗?

Doing

digits = digits | 1 << (int)((n % 10) - 1);

是一回事
long temp1 = n % 10; //Divide the number by 10 and get the remainder
long temp2 = temp1 - 1; //Subtract 1 from the remainder.
int temp3 = (int)temp2; //cast the subtracted value to int
int temp4 = 1 << temp3; //left shift 1 to the casted value. This is the same as saying "two to the power of the value of temp3"
int temp5 = digits | temp4; //bitwise or together the values of digits and that leftshifted number.
digits = temp5; //Assign the or'ed value back to digits.

最后一行

return digits == (1 << count) - 1;

的作用是一样的
int temp1 = 1 << count; //left shift 1 `count` times, this is the same as saying "two to the power of the value of count"
int temp2 = temp1 - 1; //Subtract 1 from the leftshifted number.
bool temp3 = digits == temp2; //test to see if digits equals temp2
return temp3;

我不知道"pandigital"是什么意思,但是这个分解可以帮助你理解发生了什么。

If pandigital表示"包含给定基数的所有可能的数字"

https://en.wikipedia.org/wiki/Pandigital_number

radix == 10,为什么不直接检查数字是否包含所有可能的0..9数字:

private static bool isPandigital(long n) {
  // I assume negative numbers cannot be pandigital;
  // if they can, put n = Math.Abs(n);  
  if (n < 1023456789) // smallest pandigital
    return false;
  int[] digits = new int[10];
  for (; n > 0; n /= 10) 
    digits[n % 10] += 1;
  return digits.All(item => item > 0);
} 

Edit:如果位数组 (digits中的每个表示一个数字)实现:

private static bool isPandigital(long n) {
  // negative numbers can't be pandigital 
  if (n < 1023456789) // smallest pandigital
    return false;
  int digits = 0;
  for (; n > 0; n /= 10) 
    digits |= (1 << (int)(n % 10));
  // 0b1111111111
  return digits == 1023;
}

我认为这个方法的作者试图这样做:

static bool IsPandigital(long n) {
    int digits = 0;
    while (n > 0) {
        //set the bit corresponding to the last digit of n to 1 (true)
        digits |= 1 << (int)(n % 10);
        //remove the last digit of n
        n /= 10;
    }
    //digits must be equal to 1111111111 (in binary)
    return digits == (1 << 10) - 1;
 }

<<操作符并不难。你只需要用二进制来思考。

1 & lt; & lt;0只是1移动了0位,所以1
1 & lt; & lt;1是10
1 & lt; & lt;2是100,等
如果你遇到一个2和一个5,你把它们"或"在一起,你会得到100100。
这意味着如果您遇到所有10个数字,最终结果将是10个1。

在返回语句中,检查digits是否等于10个1。
1 & lt; & lt;10代表10000000000。如果减去1,就得到1111111111
当然,所有这些都是二进制的。

他可能对pandigital有不同的定义,或者只是有不同的要求。例如,如果不允许零,您可以简单地将最后一行更改为:digits == (1 << 10) - 2;