【问题标题】:permutation combination of n variablesn个变量的排列组合
【发布时间】:2023-04-11 09:54:01
【问题描述】:

我正在经历这样一种情况,我需要找到在给定的四个变量中获取空值的可能组合。

让我解释一下:

$一个;两美元;三美元; $四;

我可能会为这些变量中的任何一个获得空值,并且需要对每种情况执行特殊操作。

我正在 PHP 中尝试。

即,

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

。 . .

我尝试使用置换公式,但无法完成。 所以我将有 24 种组合。谁能给我这个案例的简化解决方案。

提前致谢。

【问题讨论】:

  • 什么编程语言?请添加标签。
  • 你从哪里得到 24 种组合?有 4 个不同的变量,每个变量都为空或不为空,您有 16 种不同的组合。正如@jotik 所问,您使用的是什么语言?
  • 我在 PHP 中尝试这个,组合的机会是 4*3*2*1
  • 你想在所有这些情况下做出不同的反应,我说得对吗?
  • 如果你只关心每个值是否为空,那么选择数 = 2*2*2*2 = 16

标签: php switch-statement cartesian-product


【解决方案1】:

您似乎对这里的组合学感到困惑。

如果你只检查一些固定数量的字符串是否为空n,不管是哪个,这将是一个组合,并且会有 C( 4,n) 个感兴趣的案例。

如果您对哪些是空的,但只有其中 n 个是空的感兴趣,那将是一个排列,并且会有 P(4 ,n) 个感兴趣的案例。

但您似乎对哪些是空的,不管有多少感兴趣。那是笛卡尔积,你需要 2^4=16 例。

当你想枚举这样的东西时,可以把它想象成对一个四位数的二进制数进行计数,其中每个数字代表一个变量(按顺序),1表示它不为空:

  • 0000
  • 0001
  • 0010
  • 0011
  • 0100

因此,对这些可能性的蛮力线性搜索类似于

//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
}
...

但是,由于您本质上是在查看一系列布尔决策,因此我建议使用二叉搜索树。这将是一些不太漂亮的代码,但它是搜索此类内容的最有效方法(它将使用 log_2(16)=4 if 语句,而不是 16 条 - 并且没有逻辑 && 来处理)。

//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 == '') {
        ...

现在,这段代码非常高效,但也非常冗长。如果其中任何一种情况的行为方式相同,我建议尝试找到一些其他逻辑层次结构,这些层次结构将在尽可能少的步骤中决定不同的行为——但无论如何我建议一个逻辑的层次结构 而不是您尝试的线性枚举。祝你好运!

编辑: 潜伏者的建议

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

后跟switch 声明是一个比我上面的更清洁的解决方案。我想指出,底层逻辑是完全一样的;这行代码实际上是在构建我上面描述的二进制数,但是是以 10 为底的。希望你能看到我的答案和 Lurker 的对应关系,也希望我的回答能帮助你理解为什么 Lurker 的优越代码有效。

【讨论】:

    【解决方案2】:

    您可以通过执行以下操作来减少检查空值的冗余:

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

    然后使用 switch 语句检查 $n 的值,对于 16 种不同的组合,该值将介于 015 之间。

    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 ''
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多