【问题标题】:How to group factors by product and display if a product has more than one factor-pair?如果产品有多个因素对,如何按产品对因素进行分组并显示?
【发布时间】:2017-03-30 07:28:58
【问题描述】:

使用预定义的数字数组,我如何使用 PHP 生成一个多维数组,将所有因子对按其产品分组?

输入数组:

$array = array(1,2,3,4,5,6,7,8);
  • 我想显示每个产品组具有多个因子对的所有因子对。

  • 如果没有产品组具有多个因子对,则应显示No pairs Found

鉴于上述输入,这是我的预期结果:

1 6 and 2 3  // product group = 6
1 8 and 2 4  // product group = 8
2 6 and 3 4  // product group = 12
3 8 and 4 6  // product group = 24

*注意随着输入数组大小的增加,输出将显示每组超过两个因子对。

这是我的 C++ 代码:

 void findPairs(int arr[], int n)
{
    bool found = false;
    unordered_map<int, pair < int, int > > H;
    for (int i=0; i<n; i++)
    {
        for (int j=i+1; j<n; j++)
        {
            // If product of pair is not in hash table,
            // then store it
            int prod = arr[i]*arr[j];
            if (H.find(prod) == H.end())
                H[prod] = make_pair(i,j);

            // If product of pair is also available in
            // then print current and previous pair
            else
            {
                pair<int,int> pp = H[prod];
                cout << arr[pp.first] << " " << arr[pp.second]
                     << " and " << arr[i]<<" "<<arr[j]<<endl;
                found = true;
            }
        }
    }
    // If no pair find then print not found
    if (found == false)
        cout << "No pairs Found" << endl;
}

【问题讨论】:

  • 它背后的逻辑是什么?
  • 我可以在 c++ 中做同样的事情,但在 php 中不行
  • 我同意,但是输出背后的逻辑意味着你如何获得输出?或者更确切地说,您可以在这里发布您的 c++ 代码
  • 像 1*6 = 2*3 = 6 as ab= cd
  • 发布一些代码。甚至 C++ 代码也能提供帮助。

标签: php grouping elements multiplication factors


【解决方案1】:

这是您“翻译”成 PHP 的 C++ 代码(主要通过搜索和替换)。

90% 的翻译是通过删除变量类型并在变量名前加上$ 来实现的。 array PHP 类型是数组、列表和映射(又名哈希、字典)的混合体,可用于 $H 及其包含的值(值对)。

function findPairs(array $arr, $n)
{
    $found = false;
    $H = array();
    for ($i=0; $i<$n; $i++)
    {
        for ($j=$i+1; $j<$n; $j++)
        {
            // If product of pair is not in hash table,
            // then store it
            $prod = $arr[$i]*$arr[$j];
            if (! array_key_exists($prod, $H))
                $H[$prod] = array($i,$j);

            // If product of pair is also available in
            // then print current and previous pair
            else
            {
                $pp = $H[$prod];
                echo $arr[$pp[0]], " ", $arr[$pp[1]]
                     , " and ", $arr[$i], " ", $arr[$j], "\n";
                $found = true;
            }
        }
    }
    // If no pair find then print not found
    if ($found == false)
        echo "No pairs Found\n";
}

$array = array(1,2,3,4,5,6,7,8);
findPairs($array, count($array));

这是它的输出:

1 6 and 2 3
1 8 and 2 4
2 6 and 3 4
3 8 and 4 6

【讨论】:

  • 感谢@axiac 提供最佳答案
【解决方案2】:

最简单的解决方案适用于像您的示例这样的小数组,但会使用大量内存来进行更大的输入。基本上,首先使用嵌套循环计算所有产品。对于每个产品,创建一个生成产品的输入列表。请注意,获得特定结果的方法可能不止 2 种,因此对于更大的列表,您可能会得到类似 1 12 and 2 6 and 3 4 的输出。

对于大小为 N 的输入,您需要在内存中存储 ((N -1) * N) / 2 个元组,因此需要牢记这一点。

$input = [1, 2, 3, 4, 5, 6, 7, 8];

$products = [];

foreach ($input as $index1 => $value1) {
    // Assuming you only want unique combinations, only combine this value with the other values coming after it
    for ($index2 = $index1 + 1; $index2 < count($input); $index2++) {
        $value2 = $input[$index2];
        $product = $value1 * $value2;

        // Make sure there is an entry in the $products array for adding this input to
        if (!isset($products[$product])) {
            $products[$product] = [];
        }

        // Add this input (formatted) to the list of possible inputs resulting in this product
        $products[$product][] = sprintf('%d %d', $value1, $value2);
    }
}

// Print all inputs resulting in the same products, if there are more than 1 way to produce the same output
foreach ($products as $inputs) {
    if (count($inputs) > 1) {
        echo implode(' and ', $inputs), PHP_EOL;
    }
}

会输出

1 6 and 2 3
1 8 and 2 4
2 6 and 3 4
3 8 and 4 6

【讨论】:

    【解决方案3】:

    PHP code demo

    <?php
    ini_set("display_errors", 1);
    $result=array();
    $array = array(1,2,3,4,5,6,7,8);
    $counter=0;
    $noOfPairs=3;
    while (count($result)!=$noOfPairs)
    {
        shuffle($array);
        getPair($array);
    }
    print_r($result);
    function getPair($array)
    {
        global $result;
        $product=$array[0]*$array[1];
        if(isset($result[$product]))
        {
            return false;
        }
        $result[$product][]=array($array[0],$array[1]);
        unset($array[0]);
        unset($array[1]);
        foreach($array as $key1 => $value1)
        {
            foreach($array as $key2 => $value2)
            {
                if($value1*$value2==$product)
                {
                    $result[$product][]=array($value1,$value2);
                    break;
                }
            }
             if(count($result[$product])==2)
            {
                break;
            }
        }
        if(count($result[$product])==1)
        {
            unset($result[$product]);
        }
    }
    

    【讨论】:

    • 你为什么使用 $noOfPairs;像对 ab=cd 这样的条件
    • 我添加了这个$noOfPairs 以防止不必要的循环。假设您想创建 4 个组合,只需将其设为 $noOfPairs=4;
    【解决方案4】:

    我没有快速测试我的方法,但我认为它更直接且更易于阅读。
    基本上,它会生成完整的多维数组,然后过滤掉任何只有一对的子数组,然后如果还有剩余的子数组,它会显示它们。很简单。

    我的方法在没有任何count() 调用的情况下执行,也没有增加关键变量。它使用非常快速的isset() 调用来过滤结果数组,并使用array_walk() 进行迭代,并使用implode() 来筛选符合条件的子数组。

    作为一项额外功能,我使用range() 动态生成输入数组,该数组由输入数组的最大值确定。当然,如果您想找到 [3,4,5] 的配对,那么您将不得不修改此过程或简单地恢复为您的原始样式 - 这取决于您的项目期望。

    代码:(Demo)

    function findPairs($maxfactor){
        $array=range(1,$maxfactor); // spare yourself having to write out the array
        foreach($array as $v1){
            $array=array_slice($array,1); // shrink array as you go to avoid needless iterations
            foreach($array as $v2){
                $result[$v1*$v2][]="$v1 $v2";  // generate multi-dim output array using products as outer keys
            }
        }
        $result=array_filter($result,function($a){return isset($a[1]);});  // remove elements with < 2 pairs
        if(!$result){
            echo "No pairs found";
        }else{
            array_walk($result,function($a){echo implode(' and ',$a),"\n";});
        }
    }
    findPairs(8);
    

    输出:

    1 6 and 2 3
    1 8 and 2 4
    2 6 and 3 4
    3 8 and 4 6
    

    【讨论】:

      猜你喜欢
      • 2022-01-12
      • 1970-01-01
      • 2015-08-22
      • 1970-01-01
      • 2020-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多