-1

I have an interval (m,n) and there I have to print out all the numbers which have different digits. I wrote this, but it only works for 2 digit numbers. I simply do not know how to make it work for anything but 2 digit numbers. I imagine that, if I added as much for loops as the digits of my number it would work, but the interval(m,n) isn't specified so it has to be something reliable. I've been trying to solve this problem on my own for 6 damn hours and I'm absolutely fed up.

Input 97,113; Output 97,98,102,103,104,105,106,107,108,109 Numbers 99,100,101,110+ don't get printed, because they have 2 digits that are the same.

   #include<conio.h>
    #include<math.h>
    #include<stdio.h>
    int main()
    {
    int m,n,test,checker=0;
    scanf("%d%d",&m,&n);
    if(m>n)
    {
        int holder=n;
        n=m;
        m=holder;
    }

    for(int start=m;start<=n;start++)
    {
        int itemCount=floor(log10(abs(start)))+1;

        int nums[itemCount];
        int index=0;
        test=start;
        do
        {
        int nextVal = test % 10;
        nums[index++]=nextVal;
        test = test / 10;
        }while(test>0);
        for (int i = 0; i < itemCount - 1; i++) 
        { // read comment by @nbro
        for (int j = i + 1; j < itemCount; j++) 
        {
            if (nums[i] == nums[j]) 
            {
               checker++;      
            }
        }
            if(checker==0)printf("%d ",start);

        }
            checker=0;
     }
     }
  • Hi. When posting code, you can improve readability by intending it correctly. Many editors have some sort of auto-indent fuctionality. Also, can you provide some examples of expected input/output? – user1582024 Jan 06 '17 at 16:36
  • So, do you want to print permutations of given digits? – Kamil Koczurek Jan 06 '17 at 16:39
  • Instead of cramming all of the work in `main`, create a function `bool is_unique_digits(int num)` and work solely inside that function to return `true` if the number passed has unique digits, `false` otherwise. Then it becomes a simple loop in `main` -- `for (int i = startnum; i < endnum; ++i) if (is_unique_digits(i) { print the number }` – PaulMcKenzie Jan 06 '17 at 16:44
  • 1
    You have tagged C and C++ languages, which one, as they are different. For example, in C++ you can treat the number as a string with `std::string`. The C language doesn't have the `std::string` type. – Thomas Matthews Jan 06 '17 at 16:49
  • You should look at [Generate values with unique digits](http://stackoverflow.com/q/41032361) which is dealing with essentially the same problem. The framework for that problem is slightly different (the range is 0..N rather than N..M, mainly, and leading zeros are required — but not repeated leading zeros, of course). – Jonathan Leffler Jan 07 '17 at 01:01

4 Answers4

1

Since you tagged this as C++, here is a very simple solution using simple modulus and division in a loop. No conversion to string is done.

#include <iostream>
#include <bitset>

bool is_unique_digits(int num)
{
    std::bitset<10> numset = 0;
    while (num > 0)
    {
        // get last digit
        int val = num % 10;

       // if bit is on, then this digit is unique
        if (numset[val])
            return false;

        // turn bit on and remove last digit from number
        numset.set(val);
        num /= 10;
    }
    return true;
}

int main()
{
    for (int i = 97; i <= 113; ++i)
    {
        if (is_unique_digits(i))
            std::cout << i << "\n";
    }
}

The is_unique_digit function simply takes the number and repeatedly extracts the digits from it by taking the last digit in the number. Then this digit is tested to see if the same digit appears in the bitset. If the number already exists, false is immediately returned.

If the number is not in the bitset, then the bit that corresponds to that digit is turned "on" and the number is divided by 10 (effectively removing the last digit from the number). If the loop completes, then true is returned.

Live Example

PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
0

As an idea for a design:

  • print the number to a string, if it isn't a string already;

  • declare an array of int d[10]; and set it to all zeroes

  • for each ascii digit c of the string,

    if (d[c-'0']==1) return 0; // this digit exists already in the number

    else d[c-'0']= 1;

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
0

just put if(checker==0)printf("%d ",start); outside of second loop the loop

like this

for (int i = 0; i < itemCount - 1; i++)
    { 
            for (int j = i + 1; j < itemCount; j++)
            {
                if (nums[i] == nums[j])
                {
                   checker++;
                   break;
                }
            }
    }

    if(checker==0)
        printf("%d ",start);
        checker=0;

However instead of using two nested for loop you can use count array which is more efficient

Shashi Kundan
  • 343
  • 1
  • 11
-2

to check 1 number, you can do

X=10; //number to analyze
char counts[10]; for int i=0;i<10;i++) counts[i]=0;
char number[10];
sprintf(&number,"%s",X); bool bad=false;
for(int i=0;i<strlen(number);i++) 
{
 if(++counts[number[i]-'0']>1) {bad=true;break;}
}`
Miro Krsjak
  • 355
  • 1
  • 16
  • Why `char number[10];`? The number can have any length. Why is `counts` of type `char` and not of `int`? You obfuscate much with your solution proposal. You reperatedly call `strlen` where once would have been enough. – Paul Ogilvie Jan 06 '17 at 17:05