你的代码比必要的复杂了一些。
只需为每个数字计算一个“有数字”的向量(例如,如果相应的数字在数字中,则每个元素为1)。这是一个直方图/频率表,除了数字的计数之外,它只是0或1。
然后,比较向量是否相等。
这里是一些重构后的代码:
#include <stdio.h>
#include <stdlib.h>
void
count(int x,int *hasdig)
{
int dig;
if (x < 0)
x = -x;
#if 1
if (x == 0)
hasdig[0] = 1;
#endif
for (; x != 0; x /= 10) {
dig = x % 10;
hasdig[dig] = 1;
}
}
int
same_digit(int a, int b)
{
int dig_a[10] = { 0 };
int dig_b[10] = { 0 };
int dig;
int same = 1;
count(a,dig_a);
count(b,dig_b);
for (dig = 0; dig < 10; ++dig) {
same = (dig_a[dig] == dig_b[dig]);
if (! same)
break;
}
return same;
}
int
main()
{
int a, b;
scanf("%d", &a);
scanf("%d", &b);
if (same_digit(a, b))
printf("Yes\n");
else
printf("No\n");
return 0;
}
更新:
如果其中一个或两个数字是INT_MIN
,请注意UB
是的,-INT_MIN
仍然为负数:-(
我想出了另一种处理它的方法。然而,在我看来,几乎任何方法都似乎是额外的工作,只是为了使一个特殊情况起作用。因此,我保留了上面原始的[更快/更简单]代码。
而且,我添加了一些额外的测试/调试代码。
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int opt_t;
void
count(int x,int *hasdig)
{
int dig;
if (x < 0)
x = -x;
#if 1
if (x == 0)
hasdig[0] = 1;
#endif
for (; x != 0; x /= 10) {
dig = x % 10;
if (dig < 0)
dig = -dig;
hasdig[dig] = 1;
}
}
int
same_digit(int a, int b)
{
int dig_a[10] = { 0 };
int dig_b[10] = { 0 };
int dig;
int same = 1;
count(a,dig_a);
count(b,dig_b);
for (dig = 0; dig < 10; ++dig) {
same = (dig_a[dig] == dig_b[dig]);
if (! same)
break;
}
return same;
}
void
dotest(int a,int b)
{
printf("a=%d b=%d -- %s\n",
a,b,same_digit(a,b) ? "Yes" : "No");
}
int
main(int argc,char **argv)
{
char *cp;
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
cp = *argv;
if (*cp != '-')
break;
if ((cp[1] == '-') && (cp[2] == 0)) {
--argc;
++argv;
break;
}
cp += 2;
switch(cp[-1]) {
case 't':
opt_t = ! opt_t;
break;
}
}
do {
int a, b;
if (opt_t) {
dotest(4423,2433);
dotest(INT_MIN,1234678);
dotest(INT_MIN,INT_MIN);
dotest(INT_MAX,INT_MAX);
break;
}
if (argc > 0) {
for (; argc > 0; --argc, ++argv) {
cp = *argv;
if (sscanf(cp,"%d,%d",&a,&b) != 2)
break;
dotest(a,b);
}
break;
}
scanf("%d", &a);
scanf("%d", &b);
dotest(a,b);
} while (0);
return 0;
}