Solved

unique identifiers

Posted on 2006-11-19
7
233 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
>>>> 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

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

763 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

9 Experts available now in Live!

Get 1:1 Help Now