0

I am going through a situation where I need to find possible combinations of getting empty values within a given four variables.

let me explain:

$one; $two; $three; $four;

And I may get null values for any of these variables, And need to perform special action on each case.

I am trying it in PHP.

Ie,

if(($one == '') && ($two == '') && ($three == '') && ($four == '')) {
   //some action
} 
else if (($one == '') && ($two != '') && ($three == '') && ($four == '')) {
  // some action
} else if (($one != '') && ($two == '') && ($three == '') && ($four != '')) {
  // some action
}

. . .

I tried to use permutation formula, but could not complete it. So I will have 24 combinations. Can anyone give me a simplified solution for this case.

Thanks in advance.

Colin P. Hill
  • 422
  • 4
  • 18
  • 1
    What programming language? Please add a tag. – jotik Aug 14 '14 at 13:15
  • Where do you get 24 combinations? With 4 different variables, each either null or not, you have 16 different combinations. And as @jotik asks, what's the language you're using? – lurker Aug 14 '14 at 13:22
  • I am trying this in PHP, And the chances of combination is 4*3*2*1 – user3351396 Aug 14 '14 at 13:24
  • Am i right you want to react different in all those situations? – Chris311 Aug 14 '14 at 13:25
  • I need to know the background of this problem, in order to give you a more useful answer. – Chris311 Aug 14 '14 at 13:27
  • I tried with this code, but I could not convert it for my need. http://stackoverflow.com/questions/5506888/permutations-all-possible-sets-of-numbers And in my case i have four different prices, variable one = $20; variable $two = $40 And suppose if one and two are not empty, i need to set price as ($20 + $40) – user3351396 Aug 14 '14 at 13:30
  • 1
    If you only care about each value null or not, then number of choices = 2*2*2*2 = 16 – lurker Aug 14 '14 at 13:31
  • Yes, you are right, its combination of 16. – user3351396 Aug 14 '14 at 13:36

2 Answers2

0

You could reduce the redundancy of checking the nulls by doing something like this:

$n = ($one == '' ? 0 : 1) + ($two == '' ? 0 : 2) + ($three == '' ? 0 : 4) + ($four == '' ? 0 : 8)

Then use a switch statement to check the value of $n which will be between 0 and 15 for the 16 different combinations.

switch ($n) {
    case 0:
        // case where all four values are ''
        break;
    case 1:
        // case where just $one is not ''
        break;
    case 2:
        // case where just $two is not ''
        break;
    case 3:
        // case where $one and $two are not '' but $three and $four are ''
        break;

    ...

    case 15:
        // case where all four values are not ''
}
lurker
  • 56,987
  • 9
  • 69
  • 103
0

You seem to be confused on the combinatorics here.

If you were only checking whether some fixed number n of the strings were empty, regardless of which ones, that would be a combination, and there would be C(4,n) cases of interest.

If you were interested in which ones were empty, but only if exactly n of them were empty, that would be a permutation, and there would be P(4,n) cases of interest.

But it seems like you are interested in which ones are empty, regardless of how many. That is a Cartesian product, and you need 2^4=16 cases.

When you want to enumerate something like this, think of it like counting up on a four-digit binary number, where each digit represents one of the variables (in order) and 1 indicates that it is not empty:

  • 0000
  • 0001
  • 0010
  • 0011
  • 0100
  • etc.

So the brute-force linear search on these possibilities would be something like

//0000
if (($one == '') && ($two == '') && ($three == '') && ($four == '')) {
   //some action
} 
//0001
else if (($one == '') && ($two == '') && ($three == '') && ($four != '')) {
  // some action
}
//0010
else if (($one == '') && ($two == '') && ($three != '') && ($four == '')) {
  // some action
}
//0011
else if (($one == '') && ($two == '') && ($three != '') && ($four != '')) {
  // some action
}
...

However, since you're essentially looking at a series of Boolean decisions, I would suggest a binary search tree. It will be somewhat less handsome code, but it is the most efficient way to search something like this (it will take log_2(16)=4 if statements, rather than 16 -- and no logical && to process).

//Is $one empty?
if ($one == '') {

    //Yes, $one is empty. Is $two empty?
    if ($two == '') {

        //Yes, $two is empty. Is $three empty?
        if ($three == '') {

            //Yes, $three is empty. Is $four empty?
            if ($four == '') {
                //Yes, $four is empty. The case is 0000
            } else {
                //No, $four is not empty. The case is 0001
            }

        } else {

            //No, $three is not empty. Is $four empty?
            if ($four == '') {
                //Yes, $four is empty. The case is 0010
            } else {
                //No, $four is not empty. The case is 0011
            }
        }
    } else

        //No, $two is not empty. Is $three empty?
        if ($three == '') {
        ...

Now, this code is very efficient, but it is also very verbose. If any of these cases will behave in the same way, I would suggest trying to find some other logical hierarchy that will decide on distinct behaviors in as few steps as possible -- but in any case I do suggest a logical hierarchy rather than the linear enumeration you're attempting. Best of luck!

EDIT: Lurker's suggestion of

$n = ($one == '' ? 0 : 1) + ($two == '' ? 0 : 2) + ($three == '' ? 0 : 4) + ($four == '' ? 0 : 8)

followed by a switch statement is a much, much cleaner solution than mine above. I want to point out that the underlying logic is exactly the same; this line of code is in fact building the binary number I described above, but in base 10. Hopefully you can see the correspondence between my answer and Lurker's, and hopefully my answer will help you understand why Lurker's superior code works.

Colin P. Hill
  • 422
  • 4
  • 18