问题是显示在C中重复的数字。
所以我写了这个:
#include<stdio.h>
#include<stdbool.h>
int main(void){
bool number[10] = { false };
int digit;
long n;
printf("Enter a number: ");
scanf("%ld", &n);
printf("Repeated digit(s): ");
while (n > 0)
{
digit = n % 10;
if (number[digit] == true)
{
printf("%d ", digit);
}
number[digit] = true;
n /= 10;
}
return 0;
}
但它会一次又一次地显示重复的数字 (例如输入:55544输出:455)
我修改了它:
#include<stdio.h>
int main(void){
int number[10] = { 0 };
int digit;
long n;
printf("Enter a number: ");
scanf("%ld", &n);
printf("Repeated digit(s): ");
while (n > 0)
{
digit = n % 10;
if (number[digit] == 1)
{
printf("%d ", digit);
number[digit] = 2;
}
else if (number[digit] == 2)
break;
else number[digit] = 1;
n /= 10;
}
return 0;
}
有效!
但是,我想知道如果我需要使用boolean(true false)或更有效的方式怎么办?
答案 0 :(得分:2)
要使您的第一个版本正常工作,您需要跟踪两件事:
类似于:
bool seen[10] = { false };
bool output[10] = { false };
// [...]
digit = ...;
if (seen[digit]) {
if (output[digit])) {
// duplicate, but we already printed it
} else {
// need to print it and set output to true
}
} else {
// set seen to true
}
(一旦你有了这个工作,你可以简化if
。如果你把两个测试结合起来,只需要一个。)
你的第二个版本几乎就在那里,但太复杂了。您所需要做的就是:
digit = ...;
counter[digit]++;
if (counter[digit] == 2) {
// this is the second time we see this digit
// so print it out
}
n = ...;
附带好处是你可以在最后获得每个数字的计数。
答案 1 :(得分:1)
您的第二个版本代码不正确。你应该自己弄清楚你错在哪里。您可以尝试以下代码来打印重复的元素。
#include<stdio.h>
int main(void){
int number[10] = { 0 };
int digit;
long n;
printf("Enter a number: ");
scanf("%ld", &n);
printf("Repeated digit(s): ");
while (n > 0)
{
digit = n % 10;
if (number[digit] > 0)
{
number[digit]++;;
}
else if (number[digit] ==0 )
number[digit] = 1;
n /= 10;
}
int i=0;
for(;i<10; i++){
if(number[i]>0)
printf("%d ", i);
}
return 0;
}
如果您想使用bool
数组(第一个版本)打印重复元素,那么它将以相反的顺序打印元素number of times elements occur-1
,因为您正在从数字末尾分离数字,正如您在第一个版本代码输出中看到的那样。如果您只想打印一次,则必须使用上面代码中的int
数组。
答案 2 :(得分:1)
将所有输入作为字符串处理可能要容易得多:
#include <stdio.h>
#include <string.h>
int main (void) {
char str[256] = { 0 }; /* string to read */
char rep[256] = { 0 }; /* string to hold repeated digits */
int ri = 0; /* repeated digit index */
char *p = str; /* pointer to use with str */
printf ("\nEnter a number: ");
scanf ("%[^\n]s", str);
while (*p) /* for every character in string */
{
if (*(p + 1) && strchr (p + 1, *p)) /* test if remaining chars match */
if (!strchr(rep, *p)) /* test if already marked as dup */
rep[ri++] = *p; /* if not add it to string */
p++; /* increment pointer to next char */
}
printf ("\n Repeated digit(s): %s\n\n", rep);
return 0;
}
注意:您还可以添加进一步的测试,以限制只有if (*p >= '0' && *p <= '9')
的数字
<强>输出:强>
$./bin/dupdigits
Enter a number: 1112223334566
Repeated digit(s): 1236
答案 3 :(得分:0)
错误就在这里
if(number [digit] == true)
应该是
if(number [digit] == false)
Eclipse + CDT插件+步进调试 - 下次帮助
答案 4 :(得分:0)
每个人都给出了解决方案:您可以使用counting sort
see here来实现此目标。解决方案的时间复杂度为O(n)
,空间复杂度为O(n+k)
,其中k
为数字范围。
但是,您可以通过对每个元素执行XOR
操作来实现相同的目的,如果您将a XOR b
设为零,则表示重复的数字。但是,时间复杂度将是:O(n^2)
。
#include <stdio.h>
#define SIZE 10
main()
{
int num[SIZE] = {2,1,5,4,7,1,4,2,8,0};
int i=0, j=0;
for (i=0; i< SIZE; i++ ){
for (j=i+1; j< SIZE; j++){
if((num[i]^num[j]) == 0){
printf("Repeated element: %d\n", num[i]);
break;
}
}
}
}