使用PHP生成所有可能的组合
我有一系列数字,中间点缀着下划线: _10_1_1 8_4_9_14_ 我想在不涉及数字的情况下用字母替换下划线,并生成完整的组合列表,但我不知道如何操作 现在我有这个:使用PHP生成所有可能的组合,php,arrays,combinators,Php,Arrays,Combinators,我有一系列数字,中间点缀着下划线: _10_1_1 8_4_9_14_ 我想在不涉及数字的情况下用字母替换下划线,并生成完整的组合列表,但我不知道如何操作 现在我有这个: $alph = array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"); echo $alph[0]."10".$alph[0]."1".$alph[0]."18
$alph = array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z");
echo $alph[0]."10".$alph[0]."1".$alph[0]."18".$alph[0]."4".$alph[0]."9".$alph[0]."14".$alph[0] .$alph[0];
现在,我不知道如何探索所有可能的组合
有208 827 064 576种可能的组合,我必须将它们全部放在一个.txt文件中。这就是为什么我避免使用“for”
有什么想法吗
编辑:例如,我们可以将组合的数量限制为100,例如循环中有$i++
我知道这需要花费大量的时间和空间这可能不是很有效,但它会完成工作:
<?php
$alph = array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z");
$a = array();
foreach( $alph as $l1 )
{
$a[0] = $l1.'10';
foreach( $alph as $l2 )
{
$a[1] = $l2.'1';
foreach( $alph as $l3 )
{
$a[2] = $l3.'18';
foreach( $alph as $l4 )
{
$a[3] = $l4.'4';
foreach( $alph as $l5 )
{
$a[4] = $l5.'9';
foreach( $alph as $l6 )
{
$a[5] = $l6.'14';
foreach( $alph as $l7 )
{
$a[6] = $l7;
foreach( $alph as $l8 )
{
$a[7] = ' '.$l8; // your example shows a space, not sure if that was intentional
// $line = implode( '', $a )."\r\n";
// Write $line to a file
}
}
}
}
}
}
}
}
您可以利用应用于字符串的
++
运算符将环绕并生成所需的序列集这一事实,而不是使用大量嵌套循环
$str = '_10_1_18_4_9_14_ _';
$letters = str_repeat('A', substr_count($str, '_'));
$limit = 100;
for ($i = 0; $i < $limit; $i++) {
echo interpolate($str, str_split($letters)), PHP_EOL;
$letters++;
}
function interpolate($str, $letters) {
while (($pos = strpos($str, '_')) !== false) {
$str[$pos] = array_shift($letters);
}
return $str;
}
$str=''u10\u1\u18\u4\u9\u14';
$letters=str_repeat('A',substr_count($str,'uu');
$limit=100;
对于($i=0;$i<$limit;$i++){
回声插值($str,str_split($letters)),PHP_EOL;
$letters++;
}
函数插值($str,$letters){
while(($pos=strpos($str,'.'))!==false){
$str[$pos]=数组移位(字母);
}
返回$str;
}
这将问题分解为一个通用函数,该函数用字母数组替换字符串中的连续下划线,并在每次迭代中简单地从aaaaaa…
递增字符串
请参阅演示这肯定会花费很多时间-有208 827 064 576种可能的组合,我必须将它们全部放在一个.txt文件中-您绝对确定这是要求吗?因为一个18个字符的字符串的许多组合是一大堆数据。我不是说3 PB的文件不可能,但是。。。实际上这可能是不可能的。我还是想在我的电脑上试试。例如,在循环中使用$i++时,我们可以将组合数限制为100。您有文件的磁盘空间吗?是否需要将此文件发送到任何地方,如果需要,如何发送?是的,我有磁盘空间,我将其保存在计算机上。@Antoine我更新了我的示例,以输出正确的a到Z样本,而不仅仅是ABC样本。在我的测试环境中,我只有ABC,这样我的计算机就可以真正完成代码lol。此外,我在14之后的最后两个字母之间添加了空格。虽然不需要空格,但还可以。谢谢你的回答!我喜欢这个,但不幸的是,它效率非常低。对于10000000次没有输出的迭代,您的代码需要
12.8
秒,而我的代码是1.9
。我通常不是微优化的倡导者,但在这种情况下它确实很重要。@MonkeyZeus我绝对不会称之为高效,但它更容易适应不同的模式。整个问题有点奇怪,因为绝大多数磁盘(甚至文件系统)都不适合完整的输出,所以我不确定实际的用例是什么。哇,太棒了。我不知道我们也可以对字符串应用++
一元运算符。有可能在没有无数for循环的情况下循环所有组合,这对于快速开发来说是一个很好的特性。我以后肯定会用这个把戏:-)
$str = '_10_1_18_4_9_14_ _';
$letters = str_repeat('A', substr_count($str, '_'));
$limit = 100;
for ($i = 0; $i < $limit; $i++) {
echo interpolate($str, str_split($letters)), PHP_EOL;
$letters++;
}
function interpolate($str, $letters) {
while (($pos = strpos($str, '_')) !== false) {
$str[$pos] = array_shift($letters);
}
return $str;
}