• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 279
  • Last Modified:

unique identifiers

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
DJ_AM_Juicebox
Asked:
DJ_AM_Juicebox
  • 3
3 Solutions
 
UrosVidojevicCommented:
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
 
UrosVidojevicCommented:
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
 
UrosVidojevicCommented:
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
 
waysideCommented:
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
 
itsmeandnobodyelseCommented:
>>>> 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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now