What is the fastest way to check for duplicate digits of a number?

喜欢而已 提交于 2019-12-01 02:56:05

问题


Let's say I want to check if a number n = 123 has duplicate digits. I tried:

#include <iostream>

using namespace std;

int main() {
    int n = 123;
    int d1 = n % 10;
    int d2 = ( n / 10 ) % 10;
    int d3 = ( n / 100 ) % 10;
    if( d1 != d2 && d1 != d3 && d2 != d3 ) {
        cout << n << " does not have duplicate digits.\n";
    }
}

Is there any faster solution to this problem?

Update
Sorry for being unclear. The code above was written in C++ only for description purpose. I have to solve this problem in TI-89, with a number of 9 digits. And since the limitation of memory and speed, I'm looking for a fastest way possible.

TI-89 only has several condition keyword:

  • If
  • If ... Then
  • when(
  • For ... EndFor
  • While ... EndWhile
  • Loop ... EndLoop
  • Custom ... EndCustom

Thanks,
Chan


回答1:


Faster, possibly not (but you should measure anyway, just in case - my optimisation mantra is "measure, don't guess"). But clearer in intent, I think, yes, and able to handle arbitrary sized integers.

int hasDupes (unsigned int n) {
    // Flag to indicate digit has been used.

    int i, used[10];

    // Must have dupes if more than ten digits.

    if (n > 9999999999)
        return 1;

    // Initialise dupe flags to false.

    for (i = 0; i < 10; i++)
        used[i] = 0;

    // Process all digits in number.

    while (n != 0) {
        // Already used? Return true.

        if (used[n%10])  // you can cache n%10 if compiler not too smart.
            return 1;

        // Otherwise, mark used, go to next digit.

        used[n%10] = 1;  // and you would use cached value here.
        n /= 10;
    }

    // No dupes, return false.

    return 0;
}

If you have a limited range of possibilities, you can use the time-honoured approach of sacrificing space for time.

Say you're talking of numbers between 0 and 999:

const int *hasDupes = {
//  0  1  2  3  4  5  6  7  8  9
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  //   x
    0, 1, 0, 0, 0, 0, 0, 0, 0, 0,  //  1x
    0, 0, 1, 0, 0, 0, 0, 0, 0, 0,  //  2x
    :
    0, 0, 0, 0, 0, 0, 0, 1, 0, 1,  // 97x
    0, 0, 0, 0, 0, 0, 0, 0, 1, 1,  // 98x
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 99x
};

and just do a table lookup of hasDupes[n].


Based on your edit when you need to handle nine digits, a billion-element array (second solution above) is probably not going to be possible on your calculator :-)

I would opt for the first solution.




回答2:


template<class T, int radix = 10>
bool has_duplicate_digits(T n) {
    int digits_mask = 0;
    while (digits_mask |= (1 << (n % radix)), n /= radix)
        if (digits_mask & (1 << (n % radix)))
            return true;
    return false;
}

Something like that should work as long as n is nonnegative and int has at least radix bits.


digits_mask is a bitset (bit 0 represents the occurrence of a 0 digit, bit 1 represents the occurrence of a 1 digit, etc.).

The bitmap is populated with the least significant digit of n, and the rest of the digits are shifted down. If there are more digits, and the new least significant digit is marked as having occurred previously, return true, otherwise repeat.

When there are no more digits, return false.

1 << x returns 1, 2, 4, 8, etc.: masks to use to test/set bits in the bitset.

a |= z is shorthand for a = a | z, which sets bits by the union of a from z.

a & z is the intersection of the bits in a and z, and is zero (false) if none are set and non-zero (true) if any are set.




回答3:


I did a crash course in TI-89 basic to answer :)

Let's see if this works (I haven't an emulator, so can't check).

Test()
Prgm
{0,0,0,0,0,0,0,0,0,0}->A
Title "Request"
Request "Enter a number",B
EndDlog
Expr(B)->B
While  B > 1
 MOD(10,B)->C
 if A[C+1] = 1 goto K 
 1->A[C+1]
 B-C->B 
EndWhile
Title "Done"
Text "Numbers non repeating"
Enddlog
goto J

Lbl K
Title "Done"
Text "Numbers repeating"
Enddlog

Lbl J
EndPrgm


来源:https://stackoverflow.com/questions/4801487/what-is-the-fastest-way-to-check-for-duplicate-digits-of-a-number

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!