NaiveRed
NaiveRed

Reputation: 65

How to show the digits which were repeated in c?

The question is that show the digits which were repeated in C.

So I wrote this:

#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;
}

But it will show the repeated digits again and again (ex. input: 55544 output: 455)

I revised it:

#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;
}

It works!

However, I want to know how to do if I need to use boolean (true false), or some more efficient way?

Upvotes: 1

Views: 6387

Answers (5)

Amit Sharma
Amit Sharma

Reputation: 2067

As everyone has given the solution: You can achieve this using the counting sort see here. Time complexity of solution will be O(n) and space complexity will be O(n+k) where k is the range in number.

However you can achieve the same by taking the XOR operation of each element with other and in case you got a XOR b as zero then its means the repeated number. But, the time complexity will be: 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;
            }
       }
   }
}     

Upvotes: 0

David C. Rankin
David C. Rankin

Reputation: 84561

It is probably much easier to handle all the input as strings:

#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;
}

Note: you can also add a further test to limit to digits only with if (*p >= '0' && *p <= '9')

output:

$./bin/dupdigits

Enter a number: 1112223334566

  Repeated digit(s): 1236

Upvotes: 1

Amit Sharma
Amit Sharma

Reputation: 2067

Your second version code is not correct. You should yourself figured it out where are you wrong. You can try the below code to print the repeated elements.

#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;
}

In case you want to print the repeated element using bool array (first version) then it will print the elements number of times elements occur-1 times and in reverse order because you are detaching the digits from the end of number , as you are seeing in your first version code output. In case you want to print only once then you have to use int array as in above code.

Upvotes: 1

Mat
Mat

Reputation: 206689

To make your first version work, you'll need to keep track of two things:

  • Have you already seen this digit? (To detect duplicates)
  • Have you already printed it out? (To only output duplicates once)

So something like:

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
  }

(Once you've got that working, you can simplify the ifs. Only one is needed if you combine the two tests.)

Your second version is nearly there, but too complex. All you need to do is:

  • Add one to the counter for that digit every time you see it
  • Print the number only if the counter is exactly two.
digit = ...;
counter[digit]++;
if (counter[digit] == 2) {
  // this is the second time we see this digit
  // so print it out
}
n = ...;

Side benefit is that you get the count for each digit at the end.

Upvotes: 2

user3665250
user3665250

Reputation:

Error is here

if (number[digit] == true)

should be

if (number[digit] == false)

Eclipse + CDT plugin + stepping debug - help you next time

Upvotes: 0

Related Questions