Php 唯一分配选项算法
我有一个二维数组。每个子阵列由多个选项组成。我正在尝试编写一个脚本,为每行选择其中一个选项。选择的选项必须是唯一的。例如:Php 唯一分配选项算法,php,arrays,algorithm,Php,Arrays,Algorithm,我有一个二维数组。每个子阵列由多个选项组成。我正在尝试编写一个脚本,为每行选择其中一个选项。选择的选项必须是唯一的。例如: $array = array( 1 => array(3,1), 2 => array(3), 3 => array(1,5,3), ); 有一个解决方案: $array = array( 1 => 1, 2 => 3, 3 => 5, ); 我已经完成了脚本,但我不确定它是否正确。这是
$array = array(
1 => array(3,1),
2 => array(3),
3 => array(1,5,3),
);
有一个解决方案:
$array = array(
1 => 1,
2 => 3,
3 => 5,
);
我已经完成了脚本,但我不确定它是否正确。这是我的剧本。我所做的描述在评论中
function pickUnique($array){
//Count how many times each option appears
$counts = array();
foreach($array AS $options){
if(is_array($options)){
foreach($options AS $value){
//Add count
$counts[$value] = (isset($counts[$value]) ? $counts[$value]+1 : 1);
}
}
}
asort($counts);
$didChange = false;
foreach($counts AS $value => $count){
//Check one possible value, starting with the ones that appear the least amount of times
$key = null;
$scoreMin = null;
//Search each row with the value in it. Pick the row which has the lowest amount of other options
foreach($array AS $array_key => $array_options){
if(is_array($array_options)){
if(in_array($value,$array_options)){
//Get score
$score = 0;
$score = count($array_options)-1;
if($scoreMin === null OR ($score < $scoreMin)){
//Store row with lowest amount of other options
$scoreMin = $score;
$key = $array_key;
}
}
}
}
if($key !== null){
//Store that we changed something while running this function
$didChange = true;
//Change to count array. This holds how many times each value appears.
foreach($array[$key] AS $delValue){
$counts[$delValue]--;
}
//Remove chosen value from other arrays
foreach($array AS $rowKey => $options){
if(is_array($options)){
if(in_array($value,$options)){
unset($array[$rowKey][array_search($value,$options)]);
}
}
}
//Set value
$array[$key] = $value;
}
}
//validate, check if every row is an integer
$success = true;
foreach($array AS $row){
if(is_array($row)){
$success = false;
break;
}
}
if(!$success AND $didChange){
//Not done, but we made changes this run so lets try again
$array = pickUnique($array);
}elseif(!$success){
//Not done and nothing happened this function run, give up.
return null;
}else{
//Done
return $array;
}
}
函数pickUnique($array){
//计算每个选项出现的次数
$counts=array();
foreach($array作为$options){
if(is_数组($options)){
foreach(期权为$value){
//加计数
$counts[$value]=(isset($counts[$value])?$counts[$value]+1:1);
}
}
}
asort($);
$didChange=false;
foreach($counts AS$value=>$count){
//检查一个可能的值,从出现次数最少的值开始
$key=null;
$scoreMin=null;
//搜索包含值的每一行。选择其他选项数量最少的行
foreach($array AS$array\u key=>$array\u options){
if(is_数组($array_选项)){
if(在数组中($value,$array\u选项)){
//得分
$score=0;
$score=计数($array\u选项)-1;
如果($scoreMin==null或($score<$scoreMin)){
//使用最少的其他选项存储行
$scoreMin=$score;
$key=$array\u key;
}
}
}
}
如果($key!==null){
//存储我们在运行此函数时更改了某些内容
$didChange=true;
//更改为计数数组。它保存每个值出现的次数。
foreach($array[$key]作为$delValue){
$counts[$delValue]--;
}
//从其他数组中删除所选值
foreach($rowKey=>$options的数组){
if(is_数组($options)){
if(在_数组中($value,$options)){
未设置($array[$rowKey][array_search($value,$options)]);
}
}
}
//设定值
$array[$key]=$value;
}
}
//验证,检查每一行是否为整数
$success=true;
foreach($array作为$row){
if(is_数组($row)){
$success=false;
打破
}
}
如果(!$success和$didChange){
//未完成,但我们在这次运行中进行了更改,因此让我们再试一次
$array=pickUnique($array);
}elseif(!$success){
//未完成且未发生任何事件此函数运行时,放弃。
返回null;
}否则{
//完成
返回$array;
}
}
我的主要问题是,我无法验证这是否正确。其次,我也很确定这个问题已经解决了很多次,但我似乎找不到它。我可以验证这一点的唯一方法(据我所知)是对随机数组多次运行代码,并在遇到无法解决的数组时停止。然后我手动检查。到目前为止,结果是好的,但这种验证方法当然是不正确的
我希望有人能在解决方案、问题名称或验证方法方面帮助我。@MikeBrant OP说:这种验证方法当然不正确。我们只在一个时间点检查工作代码CodeReview@MikeBrant问题基本上是如何从示例数组到解决方案,我很确定这是一个已经解决的常见问题。在我看来,这就像一个@Caridorc,我想他的意思是他的代码正在工作,它在有限数量的测试输入情况下正常工作,但这本身并不能证明它在所有输入情况下都是正确的。在代码审查时,这当然可以吗?或者CR仅用于优化,而不是逻辑错误?