字符串数组的排列

发布于 2024-11-02 22:57:50 字数 1134 浏览 3 评论 0原文

我根本不知道如何解决这个问题,在谷歌上彻底搜索后没有结果,我向你求助,希望能找到解决方案。

给出下面的示例数组:(

array(
    'Type' => array(
        'Toppe',
        'Bukser_og_Jeans'
    ),
    'Size' => array(
        'Extra_small',
        'Small'
    ),
    'Colour' => array(
        'Rod'
    )
)

注意:这只是一个示例;实际的现实生活情况可能有更少/更多的组和/或每组元素)

我将如何得到以下结果?

Toppe,Extra_small,Rod
Toppe,Small,Rod
Bukser_og_Jeans,Extra_small,Rod
Bukser_og_Jeans,Small,Rod

这是一项产品搜索,API 只允许每个查询从每个类型、尺寸和颜色组中使用一个“细化”值,但我的作业需要查询和聚合多个 API 查询的结果。

认为我需要某种递归函数来完成它,但我什至无法生成任何接近我预期结果的代码。

我在谷歌上能找到的都是关于字母甚至字符串的排列,但人们需要的是“红,蓝,绿”,“蓝,红,绿”,“绿,红,蓝”等。 ,这显然不是我想要的。

我希望这里有人理解我想做什么并知道如何去做。

编辑:@ikegami 发布的解决方案已转换为 PHP:

$iter = 0;
while (1) {
    $num = $iter++;
    $pick = array();

    foreach ($refinements as $refineGroup => $groupValues) {
        $r = $num % count($groupValues);
        $num = ($num - $r) / count($groupValues);
        $pick[] = $groupValues[$r];
    }

    if ($num > 0) {
        break;
    }

    print join(', ', $pick)."\n";
}

I simply cannot wrap my head around how to solve this problem and after a thorough search on Google with no results, I turn to you with hopes of a solution.

Given the sample array below:

array(
    'Type' => array(
        'Toppe',
        'Bukser_og_Jeans'
    ),
    'Size' => array(
        'Extra_small',
        'Small'
    ),
    'Colour' => array(
        'Rod'
    )
)

(Note: This is merely a sample; the actual real life situation might have less/more groups and/or elements per group)

How would I go about ending up with the following result?

Toppe,Extra_small,Rod
Toppe,Small,Rod
Bukser_og_Jeans,Extra_small,Rod
Bukser_og_Jeans,Small,Rod

This is a product search and the API only allows ONE 'refinement' value from each of the Type, Size and Colour groups per query but my assignment requires to query and aggregate the results of multiple API queries.

I'm thinking that I need some kind of recursive function to do it, but I have been unable to even produce any code that comes close to my expected result.

All I've been able to find on Google is about permuations of letters or even strings, but where people need e.g. "Red,Blue,Green", "Blue,Red,Green", "Green,Red,Blue", etc., which is, clearly, not what I'm looking for.

I hope someone here understands what I want to do and has an idea of how to do it.

EDIT: The solution as posted by @ikegami, converted to PHP:

$iter = 0;
while (1) {
    $num = $iter++;
    $pick = array();

    foreach ($refinements as $refineGroup => $groupValues) {
        $r = $num % count($groupValues);
        $num = ($num - $r) / count($groupValues);
        $pick[] = $groupValues[$r];
    }

    if ($num > 0) {
        break;
    }

    print join(', ', $pick)."\n";
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

简单气质女生网名 2024-11-09 22:57:50

如果我们有三组,每组十个项目,我们可以使用一个从 0 到 999 的计数器,并将数字分成数字。

例如,

456 
   % 10 = 6  --------------------------  Item 6 (7th item) in the first group
   / 10 = 45
             % 10 = 5  ----------------  Item 5 (6th item) in the second group
             / 10 = 4
                       % 10 = 4  ------  Item 4 (5th item) in the third group
                       / 10 = 0

该算法将数字转换为基数 10。如果我们想转换为八进制,我们会使用 8 而不是 10。始终使用 10(或 8),因为每个位置具有相同数量的符号,但该算法如果符号数量因位置而异,也适用。

2
   % 2 = 0  ------------------------  Item 0 (1st item) in the first group: Toppe
   / 2 = 1
     ^      % 2 = 1  ---------------  Item 1 (2nd item) in the second group: Small
     |      / 2 = 0
     |        ^      % 1 = 0  ------  Item 0 (1st item) in the third group: Rod
     |        |      / 1 = 0
     |        |        ^
     |        |        |
     |        |        +------------  Number of items in third group
     |        +---------------------  Number of items in second group
     +------------------------------  Number of items in first group

这给了我们:

0 = ( 0 * 1 + 0 ) * 2 + 0 = Toppe, Extra_small, Rod
1 = ( 0 * 1 + 0 ) * 2 + 1 = Bukser_og_Jeans, Extra_small, Rod
2 = ( 0 * 1 + 1 ) * 2 + 0 = Toppe, Small, Rod
3 = ( 0 * 1 + 1 ) * 2 + 1 = Bukser_og_Jeans, Small, Rod

下面是一个 Perl 实现:

my %refinements = (
   Type => [
      'Toppe',
      'Bukser_og_Jeans',
   ],
   Size => [
      'Extra_small',
      'Small',
   ],
   Colour => [
      'Rod',
   ],
);

my @groups = values(%refinements);
my $iter = 0;
while (1) {
   my $num = $iter++;

   my @pick;
   for my $group (@groups) {
      my $r = $num % @$group;
      $num = ( $num - $r ) / @$group;
      push @pick, $group->[$r];
   }

   last if $num > 0;

   say join(', ', @pick);
}

我知道它不是 PHP——我不知道 PHP——但你只是问如何解决问题,不一定是解决问题的代码,对吧?我希望您能够充分理解上面的 Perl 代码,以解决您的问题并在 PHP 中重新实现它。

(如果我实际上正在编写 Perl 解决方案,我会使用
Algorith::Loops
NestedLoops。)

If we had three groups of ten items, we could use a counter that goes from 0 to 999, and split the number into digits.

For example,

456 
   % 10 = 6  --------------------------  Item 6 (7th item) in the first group
   / 10 = 45
             % 10 = 5  ----------------  Item 5 (6th item) in the second group
             / 10 = 4
                       % 10 = 4  ------  Item 4 (5th item) in the third group
                       / 10 = 0

This algorithm converts a number into base 10. If we wanted to convert to octal, we would have used 8 instead of 10. 10 (or 8) is used throughout because each position has the same number of symbols, but this algorithm also works if the number of symbols varies from position to position.

2
   % 2 = 0  ------------------------  Item 0 (1st item) in the first group: Toppe
   / 2 = 1
     ^      % 2 = 1  ---------------  Item 1 (2nd item) in the second group: Small
     |      / 2 = 0
     |        ^      % 1 = 0  ------  Item 0 (1st item) in the third group: Rod
     |        |      / 1 = 0
     |        |        ^
     |        |        |
     |        |        +------------  Number of items in third group
     |        +---------------------  Number of items in second group
     +------------------------------  Number of items in first group

This gives us:

0 = ( 0 * 1 + 0 ) * 2 + 0 = Toppe, Extra_small, Rod
1 = ( 0 * 1 + 0 ) * 2 + 1 = Bukser_og_Jeans, Extra_small, Rod
2 = ( 0 * 1 + 1 ) * 2 + 0 = Toppe, Small, Rod
3 = ( 0 * 1 + 1 ) * 2 + 1 = Bukser_og_Jeans, Small, Rod

The following is a Perl implementation:

my %refinements = (
   Type => [
      'Toppe',
      'Bukser_og_Jeans',
   ],
   Size => [
      'Extra_small',
      'Small',
   ],
   Colour => [
      'Rod',
   ],
);

my @groups = values(%refinements);
my $iter = 0;
while (1) {
   my $num = $iter++;

   my @pick;
   for my $group (@groups) {
      my $r = $num % @$group;
      $num = ( $num - $r ) / @$group;
      push @pick, $group->[$r];
   }

   last if $num > 0;

   say join(', ', @pick);
}

I know it's not PHP—I don't know PHP—but you're just asking how to solve the problem, not necessarily the code to do it, right? It's my hope that you can understand the above Perl code enough to solve your problem and re-implement it in PHP.

(If I was actually writing a Perl solution, I'd use
Algorith::Loops
's NestedLoops.)

紫竹語嫣☆ 2024-11-09 22:57:50

仅供那些想要 PHP 翻译的人使用:

function factor_permutations($lists) {

    $permutations = array();
    $iter = 0;

    while (true) {

        $num = $iter++;
        $pick = array();

        foreach ($lists as $l) {
            $r = $num % count($l);
            $num = ($num - $r) / count($l);
            $pick[] = $l[$r];
        }

        if ($num > 0) break;
        $permutations[] = $pick;
    }

    return $permutations;
}

print_r(factor_permutations(array(array('a', 'b'), array('1', '2', '3'), array('foo', 'bar'))));

Just for those wanting a PHP translation:

function factor_permutations($lists) {

    $permutations = array();
    $iter = 0;

    while (true) {

        $num = $iter++;
        $pick = array();

        foreach ($lists as $l) {
            $r = $num % count($l);
            $num = ($num - $r) / count($l);
            $pick[] = $l[$r];
        }

        if ($num > 0) break;
        $permutations[] = $pick;
    }

    return $permutations;
}

print_r(factor_permutations(array(array('a', 'b'), array('1', '2', '3'), array('foo', 'bar'))));
听你说爱我 2024-11-09 22:57:50
for ($i = 0; i < sizeof($Type); $i++) {
  for ($j = 0; j < sizeof($Size); $j++) {
     for ($k = 0; k < sizeof($Colour); $k++) {
       echo $Type[i] . $Size[j] . $Colour[k];
     }
  }
}
for ($i = 0; i < sizeof($Type); $i++) {
  for ($j = 0; j < sizeof($Size); $j++) {
     for ($k = 0; k < sizeof($Colour); $k++) {
       echo $Type[i] . $Size[j] . $Colour[k];
     }
  }
}
窗影残 2024-11-09 22:57:50

好吧,我不够聪明,无法理解 ikegami 的解决方案,但我能够将其转换为 Javascript 以满足我的目的。我不知道它是如何工作的,但它太棒了!

lists = [["a","b"],["x","y"],["1","2","3"]] 

function factorPermutations(lists) {  

permutations = []
$iter = 0;

while (1) {

    $num = $iter++;
    $pick = []; 

    for (l in lists) {
        $r = $num % (lists[l].length );
        $num = ($num - $r) / lists[l].length;
        $pick.push( lists[l][$r])
    } 
    if ($num > 0) break;

    permutations.push( $pick);
}
    return permutations
} 

console.log(factorPermutations(lists))

是的,我在 PHP 版本的变量上留下了一些 $ 符号。

Well I am not clever enough to comprehend ikegami's solution but I was able to convert it to Javascript for my purposes. I don't know how it works but it is brilliant!

lists = [["a","b"],["x","y"],["1","2","3"]] 

function factorPermutations(lists) {  

permutations = []
$iter = 0;

while (1) {

    $num = $iter++;
    $pick = []; 

    for (l in lists) {
        $r = $num % (lists[l].length );
        $num = ($num - $r) / lists[l].length;
        $pick.push( lists[l][$r])
    } 
    if ($num > 0) break;

    permutations.push( $pick);
}
    return permutations
} 

console.log(factorPermutations(lists))

Yeah, I left some of the $ signs on variables from the PHP version.

悟红尘 2024-11-09 22:57:50

假设您只有一层嵌套,您想要的是:

$my_ar[group1][0].(rest_of_the_group_perms[0])
$my_ar[group1][0].(rest_of_the_group_perms[1])
...
$my_ar[group1][N].(rest_of_the_group_perms[K])

也就是说,您可以将问题视为必须连接两个列表/数组。第一个是数组的第一个子数组,第二个是(递归地已经完成)其余部分。

因此,您需要一个像这样的函数:

perms($my_arr) {
   foreach($elem in $group1) {
      $return_list[] = $elem.$rest;
   }
}

其中 $group1 是数组的第一个子数组,$group_rest 是剩下的子数组。所以:

perms($my_arr) {
   $group1 = head($my_arr);
   $group_rest = tail($my_arr);

   $rest = perms($group_rest);
   $return_list = array();
   foreach($elem in $group1) {
      $return_list[] = "$elem, $rest";
   }
   return $return_list;
}

但是 $rest 也是一个数组,所以你也必须循环它:

perms($my_arr) {
   $group1 = head($my_arr);
   $group_rest = tail($my_arr);

   $rest = perms($group_rest);
   $return_list = array();
   foreach($elem in $group1) {
      foreach($relem in $rest) {
          $return_list[] = $elem.$relem;
      }
   }
   return $return_list;
}

添加结束条件(null $group_rest),然后你就设置好了:

perms($my_arr) {
   $group1 = head($my_arr);
   $group_rest = tail($my_arr);

  if (length($group_rest) == 0) 
       $rest = array();
  else
       $rest = perms($group_rest);
   $return_list = array();
   foreach($elem in $group1) {
      foreach($relem in $rest) {
          $return_list[] = $elem.$relem;
      }
   }
   return $return_list;
}

Supposing you have only one nesting level, what you want is:

$my_ar[group1][0].(rest_of_the_group_perms[0])
$my_ar[group1][0].(rest_of_the_group_perms[1])
...
$my_ar[group1][N].(rest_of_the_group_perms[K])

that is, you can see the problem as having to join two lists/arrays. The first being the first subarray of your array and the second being the (recursively already made) rest.

So you need a function like this:

perms($my_arr) {
   foreach($elem in $group1) {
      $return_list[] = $elem.$rest;
   }
}

where $group1 is the first subarray of your array and $group_rest is what is left. So:

perms($my_arr) {
   $group1 = head($my_arr);
   $group_rest = tail($my_arr);

   $rest = perms($group_rest);
   $return_list = array();
   foreach($elem in $group1) {
      $return_list[] = "$elem, $rest";
   }
   return $return_list;
}

but $rest is also an array so you have to loop over that too:

perms($my_arr) {
   $group1 = head($my_arr);
   $group_rest = tail($my_arr);

   $rest = perms($group_rest);
   $return_list = array();
   foreach($elem in $group1) {
      foreach($relem in $rest) {
          $return_list[] = $elem.$relem;
      }
   }
   return $return_list;
}

add the ending condition (null $group_rest) and you are set:

perms($my_arr) {
   $group1 = head($my_arr);
   $group_rest = tail($my_arr);

  if (length($group_rest) == 0) 
       $rest = array();
  else
       $rest = perms($group_rest);
   $return_list = array();
   foreach($elem in $group1) {
      foreach($relem in $rest) {
          $return_list[] = $elem.$relem;
      }
   }
   return $return_list;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文