如果产品具有多个因子对,如何按产品对因子进行分组并显示?
How to group factors by product and display if a product has more than one factor-pair?
使用预定义的数字数组,我如何使用 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;
}
最简单的解决方案适用于像您的示例这样的小型数组,但会使用大量内存来处理更大的输入。基本上,首先使用嵌套循环计算所有产品。对于每个产品,创建生成产品的输入列表。请注意,可能有超过 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
<?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]);
}
}
这是您从 "translated" 到 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
我没有对我的方法进行速度测试,但我认为它更直接也更容易阅读。
基本上,它生成完整的多维度数组,然后过滤掉任何只有一个的子数组对,然后如果还有剩余的子数组,它会显示它们。简单。
我的方法执行时没有任何 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
使用预定义的数字数组,我如何使用 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;
}
最简单的解决方案适用于像您的示例这样的小型数组,但会使用大量内存来处理更大的输入。基本上,首先使用嵌套循环计算所有产品。对于每个产品,创建生成产品的输入列表。请注意,可能有超过 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
<?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]);
}
}
这是您从 "translated" 到 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
我没有对我的方法进行速度测试,但我认为它更直接也更容易阅读。
基本上,它生成完整的多维度数组,然后过滤掉任何只有一个的子数组对,然后如果还有剩余的子数组,它会显示它们。简单。
我的方法执行时没有任何 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