2017-02-10 25 views
-1

Я столкнулся с этим решением, проверяя, является ли число pandigital (n-значный номер, который использует все цифры от 1 до n ровно один раз, например, 1234).Как работает проверка числа pandigital?

private boolean isPandigital(int n){ 
    int digits = 0; 
    int numDigits = String.valueOf(n).length(); 
    for (; n > 0; n /= 10){ 
     digits += (1 << (n - ((n/10) * 10) - 1)); 
    } 
    return digits == ((1 << numDigits) - 1); 
} 

Цикл for берет цифру с каждого цикла (1234,123,12,1). Внутри цикла:

(n - ((n/10) * 10) - 1) 

к расценивается последней цифре п и увозит 1.

Я понимаю, что метод физически делает, но то, что свойство Pandigital чисел это эксплуатируют?

+2

'(n - ((n/10) * 10)' является очень неудобным способом записи 'n% 10' –

+0

, почему C# тег? Ни' boolean', ни 'String.valueOf' не регенерируется C# компилятор –

ответ

3

свойство это эксплуатируют является то, что для Pandigital ввода длины п, суммируя цифры должны быть равны (п + (п - 1) + (п - 2). .. + 1), что эквивалентно (n * (n + 1))/2. Но вместо того, чтобы делать алгоритм в десятичном виде, функция выполняет его с двоичными битами.

Он использует каждую десятичную цифру для увеличения двоичной цифры. Для десятичной цифры d двоичный бит в (d - 1) увеличивается. то есть десятичная цифра 3 становится (1 < < (3 - 1)), которая будет увеличивать вторую двоичную цифру. Они суммируются и сравниваются с ожидаемым значением. Ожидаемое значение состоит в том, что каждая двоичная цифра будет установлена ​​для длины вашего ввода. Если ваш вход 1234, каждый двоичный бит будет установлен для 4-битного двоичного значения (1111 в двоичном формате = 15 в десятичном значении от ((1 << numDigits) - 1)).

0

Конкретное свойство не используется.

Фокус в том, что когда вы находите цифру i, вы добавляете (2 к мощности i) к переменным цифрам, то есть устанавливаете один бит в этом целое. В конце процесса число n цифр будет pandigital, если цифры = (2 для мощности i) -1, то есть n младших разрядов цифр, установленных на 1.

Просто для удовольствия, вы может сделать это в рекурсивным образом:

bool ispandigital = testpandigital(n.ToString()) ; 

private bool testpandigital(string nbr) 
{ 
    string digit=str.Length.ToString() ; 
    return nbr=="0" || (nbr.Contains(digit) && testpandigital(nbr.Replace(digit,"")) ; 
} 
+0

«но какое свойство pandigital номеров использует?» .... хотя мне нравится рекурсия ... –

+0

@MongZhu: никакого специального свойства не используется. Фокус в том, что, когда вы найдете цифру * i *, вы добавьте * (2 к мощности i) * в переменную * цифры *, то есть установите один бит в это целое число. В конце процесса число * n * цифр будет pandigital, если * цифры * = * (2 к мощности i) -1 *, т. Е. N младших бит * цифр * все установлено в 1. – Graffito

+0

У меня такое ощущение, что это принадлежит вашему сообщению, так как это звучит точно, о чем спрашивает opp. быть двоичным представлением :) –