Solved

unique identifiers

Posted on 2006-11-19
7
246 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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

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

Suggested Solutions

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
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 viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

773 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