假设我想检查数字n = 123是否有重复的数字。我试过了:
#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";
}
}
有没有更快的解决方案来解决这个问题?
更新
很抱歉不清楚。上面的代码是用C ++编写的,仅用于描述目的。我必须在TI-89中解决这个问题,其中包含9位数字。由于内存和速度的限制,我正在寻找一种最快的方式。
TI-89只有几个条件关键字:
谢谢,
陈
答案 0 :(得分:10)
更快,可能没有(但你应该测量,以防万一 - 我的优化口号是"measure, don't guess"
)。但是,我认为,更明确的意图是,能够处理任意大小的整数。
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;
}
如果您的可能性有限,您可以使用历史悠久的牺牲空间的方法。
假设你在谈论0到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
};
只需查看hasDupes[n]
。
根据你需要处理九位数的编辑,你的计算器可能无法实现十亿元素数组(上面的第二个解决方案): - )
我会选择第一个解决方案。
答案 1 :(得分: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;
}
只要n
为非负且int
至少有radix
位,就应该有效。
digits_mask
是一个bitset(第0位表示出现0位,第1位表示出现1位数等)。
位图填充了n
的最低有效位,其余数字向下移位。如果有更多数字,并且新的最低有效数字被标记为先前已发生,则返回true,否则重复。
如果没有更多数字,则返回false。
1 << x
返回1,2,4,8等:用于测试/设置位集中位的掩码。
a |= z
是a = a | z
的简写,它按来自a
的{{1}}的联合设置位。
z
是a & z
和a
中的位的交集,如果没有设置则为零(false),如果设置则为非零(true)。< / p>
答案 2 :(得分:1)
我在TI-89基础上做了速成课程来回答:)
让我们看看这是否有效(我没有模拟器,所以无法检查)。
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