Solved

unique identifiers

Posted on 2006-11-19
7
241 Views
Last Modified: 2010-05-18
Hi,

I need a system of making exclusive number codes. Say i have a few products, like:

    hammer
    drill
    wedge

and then I just enumerate them:

    enum {
        hammer = 0,
        drill,
        wedge
    }

how can I make a number that uniquely identifies any combination of them? Like I get the #6 and that is the combination of hammer and wedge - a zero means only a hammer, etc. I don't have any requirements, just that when I get the final number, I can decompose it into the product types that made it up.

Thanks
0
Comment
Question by:DJ_AM_Juicebox
  • 3
7 Comments
 
LVL 7

Accepted Solution

by:
UrosVidojevic earned 168 total points
ID: 17976212
If you have n products:

for example:

product1, product2, product3,..,productn

then you can get that unique number from formula:

product_1_used * 2^0 + product_2_used * 2^1 + product_3_used * 2^3 + ... + product_n_used * 2^(n-1)

where ^ is a power operation, and

product_i_used is 1 if product i is in group, and 0 if this is not the case.

for example if you have: hammer, drill, wedge and you need to identify set (hammer, wedge), you will get number:

hamer_used * 2^0 + drill_used * 2^1 + wedge_used * 2^2 =
1*2^0 + 0*2^1 + 1*2^2 =
1 + 0 + 4 =
5.
0
 
LVL 7

Expert Comment

by:UrosVidojevic
ID: 17976270
It is also very nice, that products are numbered from 0 to n-1,

so your formula is actualy:

hamer_used * 2^hammer + drill_used * 2^drill + wedge_used * 2^wedge

================
On the other side, if you have an unique number k, and you want to know which tools are in group, the process is more complex but not very hard.

product_1_used = k % 2; k = k / 2;
product_2_used = k % 2; k = k / 2;
...
product_n_used  = k % 2.

where % is mod operation.

In your example, let suppose we have number 6, so: k=6,
hammer_used = 6 % 2 = 0; k = k / 2 = 3;
drill_used = 3 % 2 = 1; k =3 / 2 = 1;
wedge_used = 1 % 2 = 1;

So number 6 means that drill and wedge are used.

I will post some sample code soon.
0
 
LVL 7

Expert Comment

by:UrosVidojevic
ID: 17976349
Sample code:
=============
_______________________________________________________________________________
#include <iostream>
#include <string>
using namespace std;

const int tools_num = 4;

enum Tools {
      hammer = 0,
      drill,            // = 1
      wedge,            // = 2
      screwdriver      // = 3
};

string toolName (Tools t) {
      switch (t) {
            case 0: return "hammer"; break;
            case 1: return "drill"; break;
            case 2: return "wedge"; break;
            case 3: return "screwdriver"; break;
      }
}

int main() {
      int k;
      cout << "Enter unique number: ";
      cin >> k;

      int tool_used[tools_num];
      for (int i = 0; i < tools_num; i++) {
            tool_used[i] = k % 2;
            k = k / 2;
      }

      cout << "Tools in group: ";
      for (int i = 0; i < tools_num; i++)
            if (tool_used[i])
                  cout << toolName(Tools(i)) << " ";
      cout << endl;
      cin.get();
}
_______________________________________________________________________________



Sample input\output 1:
======================

__________________________________________
Enter unique number: 6
Tools in group: drill wedge
__________________________________________



Sample input\output 2:
======================

__________________________________________
Enter unique number: 15
Tools in group: hammer drill wedge screwdriver
__________________________________________


Note that probably using an enum in this case is not best idea, since you cannot automaticaly convert, Enum variable into it's string equivalent (drill (=1) into string "drill").
Maybe it is better to make an array of strings where i-th string is the name of i-th product/tool.

It is also more flexible since user can give product names and number that in this case are not limited like when using enum.

Hope this helps, Uros.
0
 
LVL 14

Assisted Solution

by:wayside
wayside earned 166 total points
ID: 17982702
Use bitmasks:

    enum {
        hammer = 0x01,  // binary 0001
        drill        = 0x02,  // binary 0010
        wedge   = 0x04  // binary 0100
    }

   int prodnum = 6; // 0x06  or binary  0110

   // use binary AND's to decompose prodnum
   if (prodnum & hammer) {
      // I have a hammer
   }

   if (prodnum & drill) {
      // I have a drill
   }

   if (prodnum & wedge) {
      // I have a wedge
   }
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 166 total points
ID: 17986193
>>>> how can I make a number that uniquely identifies any combination of them?

I personally prefer using three enumerations ( if the count of objects is limited to less than 32  and if the number of (valid or used) combinations is limited as well, say less than 100:

enum {
  hammer,
  drill,
  wedge,
  max_tools   // must be last
};

Note, hammer is 0 by default and max_tools automatically counts the objects.


The following enumeration sets the corresponding bit for each tool.

enum {
    HAMMER = 1 << hammer,
    DRILL = 1 << drill,
    WEDGE = 1 << wedge
};

With that you can write functions like that:

boolf(unsigned int usedTools)
{
     // check for hammer
     if (usedTools & HAMMER)
     {
             ....
     }
}

and you can call f(...) like

   if ( f( WEDGE | DRILL ) )
   {
        ...
   }  
   
If there are combinations that you want to name separatedly you could define a further enumeration:

enum ToolCombination
{
      HAMMER_WEDGE = HAMMER | WEDGE,
      DRILL_ONLY = DRILL,
      DRILL_WEDGE = DRILL | WEDGE,
      MAX_TC = 3    // unfortunately you can't count them automatically
};

const char*        allTools[max_tools] = { "hammer", "drill", "wedge", };
ToolCombination allToolCombs[MAX_TC] = {  HAMMER_WEDGE,  DRILL_ONLY,  DRILL_WEDGE, };

With that you can test whether a given combination is valid:

bool checkToolCombination(int usedTools)
{
     for (int i = 0; i < MAX_TC; ++i)
         if (usedTools == allToolCombs[i])
                return true;
     
    cout << "The combination of ";    

     for (int j = 0; j < max_tools; ++j)
          if (usedTools & (1 << j))
               cout << allTools[j] << " ";

    cout << "is not a valid tool combination." << endl;
    return false;
}


Regards, Alex



0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

914 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now