我可以使用数组创建独特的组合,但我不能将某些字段设置为默认值。
我试图改变所有的置换和组合功能。首先,如果 col2 等于“e”字母,我会回显。但这不是正确的方法。
function FindWord( $word = '', $in = [] ) {
return array_filter($in, function($s) use($word) { return $s==$word; });
}
function CreateLines2($Keywords=[], $Format=[], $Exclude=[], $Col=0, $nth=0){
$Row = $Format;
$RowOK=true;
foreach($Row AS $key=>$val){
if ($Col==$key){
$SearchIn=array_diff($Keywords,$Exclude);
if (!count($SearchIn) || !($Next=FindWord( '*', $SearchIn )[0]??false)){
$RowOK = false;
$nth = 0;
$Col ++;
//vd($Col.'-'.$nth,0);
//break;
} else {
$Exclude[]=$Row[$key]=$Next;
}
} else {
if (strpos( $val, '*' ) !== false){
$Row[$key]=FindWord( $val, array_diff($Keywords,$Exclude) )[0];
} else {
$Row[$key]=$val;
}
$Exclude[]=$Row[$key];
}
}
if ($RowOK){
$result = implode( ",", $Row ) . "\n";
echo $Col . "/" . $nth . " - " . $result . "<br>";
//file_put_contents( resultFile, $result, FILE_APPEND );
ob_flush();
flush();
}
CreateLines2( $Keywords, $Row, $Exclude, $Col, $nth + 1 );
}
CreateLines2( [ 'a', 'b', 'c', 'd', 'e', 'f', 'g' ], [ '*', 'e', '*', 'g' ] );
结果的开始是正确的,但是当它传递给第二列时,我得到了相同的结果。
a,e,b,g
c,e,b,g
d,e,b,g
f,e,b,g
f,e,b,g
f,e,b,g
f,e,b,g
f,e,b,g
f,e,b,g
f,e,b,g
f,e,b,g
f,e,b,g
例如,我有 4 列。第二列必须是默认值“e”,第四个默认值是“g”。其他必须与第一个数组一起更改。但所有行都必须是唯一的。
我需要这个结果:
CreateLines2( [ 'a', 'b', 'c', 'd', 'e'], [ '*', 'e', '*', ] );
a,e,b
c,e,b
d,e,b
b,e,a
c,e,a
d,e,a
a,e,c
b,e,c
d,e,c
a,e,d
b,e,d
c,e,d
- 我在第一个数组中有更多值。但是结果组合数组必须是特定的计数。
- 我无法将结果保存在 RAM 中。因为我的组合将是百万数据。所以我将每一行附加到文件中。
编辑#2
function CreateLines3($Keywords=[], $Defaults=[], $Format=[], $Exclude=[], $Col=0, $nth=0){
if (!count($Format)) {
$Format = $Defaults;
$Exclude = array_filter($Defaults, function($s){return strpos($s,'*')===false;});
}
$RowOK=true;
foreach($Format AS $key=>$val){
if ($Col==$key){
if (strpos($Defaults[$key],'*')===false){
$RowOK = false;
$Exclude[]=$Format[$key];
} else {
$SearchIn=array_diff($Keywords,$Exclude);
if (!count($SearchIn) || !($Next=FindWord( '*', $SearchIn )[0]??false)){
$RowOK = false;
} else {
$Exclude[]=$Format[$key]=$Next;
}
}
}
else {
if (strpos( $val, '*' ) !== false){
$Format[$key]=FindWord( $val, array_diff($Keywords,$Exclude) )[0];
} else {
$Format[$key]=$val;
}
$Exclude[]=$Format[$key];
}
}
if ($RowOK){
$result = implode( ",", $Format ) . "\n";
echo $Col . "/" . $nth . " - " . $result . "<br>";
$nth++;
ob_flush();
flush();
} else {
$Col ++;
if ($Col>=count($Format)){
return false;
}
$Exclude=[];
$nth = 0;
}
CreateLines3( $Keywords, $Defaults, $Format, $Exclude, $Col, $nth );
}
//CreateLines3( [ 'a', 'b', 'c', 'd', 'e'], [ '*', 'e', '*', ] );
CreateLines3( [ 'a', 'b', 'c', 'd', 'e', 'f', 'g' ], [ '*', 'a', 'g', '*' ] );
新的缺失结果:
0/0 - b,a,g,c
0/1 - d,a,g,c
0/2 - e,a,g,c
0/3 - f,a,g,c
3/0 - f,a,g,b
3/1 - f,a,g,c
3/2 - f,a,g,d
3/3 - f,a,g,e
终于解决了,但我有一个内存问题。
我在 PHP 的 Permutations/combinations中使用 start pick() 更新了函数
function CPerm($words, $num, $picked = [], $Format=[]) {
for ($i = 0; $i < count($words); $i += 1) {
$word = $words[$i];
$remaining_words = array_diff($words, [$word]);
if ($num > 1) {
// pick the remaning $num-1 words
CPerm(array_values($remaining_words), $num - 1, array_merge($picked, [$word]), $Format);
} else {
$result = array_merge($picked, [$word]);
$Save=true;
foreach($result AS $key=>$val){
if (strpos($Format[$key],'*')!==false){
if (!preg_match( "/" . str_replace( "*", "(.*?)", $Format[$key] ) . "/i", $result[$key] ) ) {
$Save=false;
}
} else {
if ($result[$key]!=$Format[$key]){
$Save=false;
}
}
}
if ($Save) {
$keywords = implode(",", $result) . "\n";
echo $i." -" .$keywords."<br>";
file_put_contents( resultFile, $keywords, FILE_APPEND );
}
}
}
}
CPerm(range('a', 'g'), 4, [], [ '*', 'a', 'e', '*' ]);
成功的结果:
0 -b,a,e,c
1 -b,a,e,d
2 -b,a,e,f
3 -b,a,e,g
0 -c,a,e,b
1 -c,a,e,d
2 -c,a,e,f
3 -c,a,e,g
0 -d,a,e,b
1 -d,a,e,c
2 -d,a,e,f
3 -d,a,e,g
0 -f,a,e,b
1 -f,a,e,c
2 -f,a,e,d
3 -f,a,e,g
0 -g,a,e,b
1 -g,a,e,c
2 -g,a,e,d
3 -g,a,e,f
如果我增加数组 1 组合,开始内存问题。
CPerm(range('a', 'z'), 6, [], [ '*', 'a', 'e', '*' , '*' , '*' ]);