计算数组值

时间:2015-08-18 21:00:03

标签: php arrays

我有一个55.9毫米的被测量,我想把它分成不同的量块。就像: 55.9mm = 1.4mm + 1.5mm + 50mm + 3mm

但是我可能没有1.4规格块。所以我需要使用类似的东西:

55.9mm = 1.44mm + 1.46mm + 50mm + 3mm

如您所见,我必须替换1.4和1.5规格块。

我正在编写一个PHP脚本,根据可用的量块来计算我可以使用哪些可能的量块。

如何检查,两个小数位的量块替换一个小数位的量块。

可用块存储在数组中。

以下是完整的代码:

<?php

function decimalPlaces($number) {
    $str = strval($number);
    $pos = strrpos($number, '.');
    return ($pos===false ? 0 : strlen($str)-$pos-1);
}

function gaugeBlocks($measurement, $em0, $em1, $em2, $em3){
    if($measurement == 0){
    return;
}
$dp = decimalPlaces($measurement);
$gauge = array();

if($dp == 3){
    foreach($em3 as $em){
        $newMeasurement = round($measurement, 3) - $em;
        if(decimalPlaces($measurement - $em) == 2){
            echo "Neuer Messwert: ".$newMeasurement." nach Abzug des Endmasses: ".$em."<br />";
            $gauge[] = $em;
            if($newMeasurement == 0){
                echo "HELL NO 3";
            }else{
                gaugeBlocks($newMeasurement, $em0, $em1, $em2, $em3);
            }
        }
    }
}

if($dp == 2){
    $splitDec = explode(".", round($measurement, 2));
    $zielEM = floatval("1.".$splitDec[1]);

    if($zielEM < 1.50){
        foreach($em2 as $em){
            if($em == $zielEM){
                $newMeasurement = round($measurement, 2)-$em;
                echo "Neuer Messwert: ".$newMeasurement." nach Abzug des Endmasses: ".$em."<br />";
                if(decimalPlaces($newMeasurement) == 1 || decimalPlaces($newMeasurement) == 0){
                    $gauge[] = $em;
                    if($newMeasurement == 0){
                        echo "HELL NO 2";
                    }else{
                        gaugeBlocks($newMeasurement, $em0, $em1, $em2, $em3);
                    }
                }
            }else{
                $lastDigitMeasurement = floatval(substr($measurement, -1));
                $lastDigitEM = floatval(substr($em, -1));
                if($lastDigitEM == $lastDigitMeasurement){
                    $newMeasurement = round($measurement, 2)-$em;
                    echo "Neuer Messwert: ".$newMeasurement." nach Abzug des Endmasses: ".$em."<br />";
                    if(decimalPlaces($newMeasurement) == 1 || decimalPlaces($newMeasurement) == 0){
                        $gauge[] = $em;
                        if($newMeasurement == 0){
                            echo "HELL NO 2";
                        }else{
                            gaugeBlocks($newMeasurement, $em0, $em1, $em2, $em3);
                        }
                    }
                }
            }
        }
    }else{
        $nextEM = $zielEM-0.5;
        foreach($em2 as $em){
            if($em == $nextEM){
                echo "da noch?";
                $newMeasurement = round($measurement, 2)-$em;
                echo "Neuer Messwert: ".$newMeasurement." nach Abzug des Endmasses: ".$em."<br />";
                if(decimalPlaces($newMeasurement) == 1 || decimalPlaces($newMeasurement) == 0){
                    $gauge[] = $em;
                    if($newMeasurement == 0){
                        echo "HELL NO 2";
                    }else{
                        gaugeBlocks($newMeasurement, $em0, $em1, $em2, $em3);
                    }
                }
            }
        }

    }
}

if($dp == 1){
    $splitDec = explode(".", round($measurement, 1));
    $zielEM = floatval("1.".$splitDec[1]);
    if($zielEM <= 1.5){
        foreach($em1 as $em){
            if($em == $zielEM){
                $newMeasurement = round($measurement, 1)-$em;
                echo "Neuer Messwert: ".$newMeasurement." nach Abzug des Endmasses: ".$em."<br />";
                if(decimalPlaces($newMeasurement) == 1 || decimalPlaces($newMeasurement) == 0){
                    $gauge[] = $em;
                    if($newMeasurement == 0){
                        echo "HELL NO 2";
                    }else{
                        gaugeBlocks($newMeasurement, $em0, $em1, $em2, $em3);
                    }
                }
            }else{

                $lastDigitMeasurement = floatval(substr($measurement, -1));
                $lastDigitEM = floatval(substr($em, -1));
                if($lastDigitEM == $lastDigitMeasurement){
                    $newMeasurement = round($measurement, 1)-$em;
                    echo "Neuer Messwert: ".$newMeasurement." nach Abzug des Endmasses: ".$em."<br />";
                    if(decimalPlaces($newMeasurement) == 1 || decimalPlaces($newMeasurement) == 0){
                        $gauge[] = $em;
                        if($newMeasurement == 0){
                            echo "HELL NO 2";
                        }else{
                            gaugeBlocks($newMeasurement, $em0, $em1, $em2, $em3);
                        }
                    }
                }
            }
        }
    }else{
        $nextEM = $zielEM-0.5;
        foreach($em1 as $em){
            if($em == $nextEM){
                $newMeasurement = round($measurement, 1)-$em;
                echo "Neuer Messwert: ".$newMeasurement." nach Abzug des Endmasses: ".$em."<br />";
                if(decimalPlaces($newMeasurement) == 1 || decimalPlaces($newMeasurement) == 0){
                    $gauge[] = $em;
                    if($newMeasurement == 0){
                        echo "HELL NO 2";
                    }else{
                        gaugeBlocks($newMeasurement, $em0, $em1, $em2, $em3);
                    }
                }
            }else{
                $lastDigitMeasurement = floatval("2.".substr($measurement, -1));
                //Solve problem here...


            }
        }

    }
}

if($dp == 0){
    foreach($em0 as $em){
        $em = round($em, 0);
        $newMeasurement = round($measurement, 0) - $em;
        if($newMeasurement >= 0){
            echo "Neuer Messwert: ".$newMeasurement." nach Abzug des Endmasses: ".$em."<br />";
            $gauge[] = $em;
            gaugeBlocks($newMeasurement, $em0, $em1, $em2, $em3);
        }
        if($newMeasurement == 0){
            exit;               
        }
    }
}

return; 
}

echo "<a href='menu.php'>Zurück</a><br />";
echo "<br />";
echo $_POST["mass"];
echo "<br />";



$tray = array();
if($_POST["halle"] == 1){
    $tray = ["W7", "W8"];
}
if($_POST["halle"] == 2){
    $tray = ["W4", "W10"];
}

$em3 = ["1.005"];
$em2 = array();
$em1 = array();
$em0 = array();

$wert = 1;
$em1 = [0.5];
$em0[] = $wert;
while($wert<1.5){
    $wert = $wert+0.01;
    if(decimalPlaces($wert) == 2){
        $em2[] = $wert;
    }else{
        $em1[] = $wert;
    }
}
$wert = 1.5;
while($wert<25){
    $wert = $wert+0.5;
    if(decimalPlaces($wert) != 0){
        $em1[] = $wert;
    }else{
        $em0[] = $wert;
    }
}
$wert = 25;
while($wert<100){
    $wert = $wert+25;
    $em0[] = $wert;
}

/*
 * Alle Möglichen Stückelungen mit vorhandenen Maßen
 */
$measurement = floatval(str_replace(',', '.', $_POST['mass']));
$usedBlocks = array();
$em3 = array_reverse($em3);
foreach(array_keys($em3) as $em){
    $em3[$em] = round($em3[$em], 3);
}

$em2 = array_reverse($em2);
foreach(array_keys($em2) as $em){
    $em2[$em] = round($em2[$em], 2);
    if(($em2[$em] == 1.37)){
        unset($em2[$em]);
    }
}



$em1 = array_reverse($em1);
foreach(array_keys($em1) as $em){
    $em1[$em] = round($em1[$em], 1);
    if(($em1[$em] == 1.4)){
        unset($em1[$em]);
    }
}

$em0 = [100, 75, 50, 25, 24, 23, 22, 21, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 2, 1];
foreach(array_keys($em0) as $em){
    $em0[$em] = round($em0[$em], 0);
}


$usedBlocks[] = gaugeBlocks($measurement, $em0, $em1, $em2, $em3);

?>

1 个答案:

答案 0 :(得分:1)

例如gaugeArray = [1,4,11.3,48.6];

阵列中有4个元素2 ^(4)= 16个可能的结果。

由二进制位表示的组合:

(1)0000 (2)0001 (3)0010 (4)0011 (5)0100 (6)0101 (7)0110 (8)0111 (9)1000 (10)1001 (11)1010 (12)1011 (13)1100 (14)1101 (15)1110 (16)1111

所以,你可以尝试:

<?php

$gaugeString = filter_input(INPUT_GET, 'gauges');
$desired = filter_input(INPUT_GET, 'desired');

$gaugeArray = array();
$need2RunRoutine = false;
$desiredValue  = 12.6;
if(isset($gaugeString) && isset($desired))
{
	$gaugeStringSplits = explode(",", $gaugeString);
	for($i=0; $i<count($gaugeStringSplits); $i++)
	{
		array_push($gaugeArray, floatval($gaugeStringSplits[$i]));
	}
	$desiredValue  = floatval($desired);
	$need2RunRoutine = true;
}
else
{
	$gaugeArray = array(1, 4, 11.3, 48.6);
}
$gaugeInputString = "";
for($i=0; $i<count($gaugeArray); $i++)
{
	$gaugeInputString .= ($gaugeArray[$i].', ');
}
$gaugeInputString = trim($gaugeInputString, ',');
$gaugeInputString = trim($gaugeInputString, ', ');
echo '<form method="GET">Enter gauges(seperated by ,):<br><input type="text" name="gauges" value="'.$gaugeInputString.'"><br>Enter Desired Length:<br><input type="text" name="desired" value="'.$desiredValue.'"><br><input type="submit"></from>';
if($need2RunRoutine)
{
	$bitSelector = array();
	for($i=0; $i<count($gaugeArray); $i++)
	{
		array_push($bitSelector, (0x01<<$i) );
	}
  
	$possibleOutcomesCount = pow(2,count($gaugeArray));
	//echo '$possibleOutcomesCount: '.$possibleOutcomesCount;
	$possibleCombinations = array();  //will contain all possible outcomes

	for($i=0; $i<$possibleOutcomesCount; $i++)     //16  combinations
	{
  		$combineValue = 0;
  		for($j=0; $j<count($gaugeArray); $j++)
  		{
    		if( ($i & $bitSelector[$j]) == $bitSelector[$j])
    		{
      			$combineValue  += $gaugeArray[$j];
    		}
  		}
		//echo '<br>'.$combineValue.'<br>';
  		array_push($possibleCombinations, $combineValue);
	}

	//after this you need to select the value which is most close to your desired value from $possibleCombinations
	$bestMatch = -1;
	$matchIndex = -1;
	for($i=0; $i<count($possibleCombinations); $i++)
	{
  		if( ($bestMatch < $possibleCombinations[$i]) && ($possibleCombinations[$i] <= $desiredValue) )
    	{
      		$bestMatch = $possibleCombinations[$i];
			$matchIndex = $i;
    	}
	}
	if($matchIndex >= 0)
	{
		echo '<br><br><br>Best Match value: '.$bestMatch.'<br>';
		$outputString = '';
		for($i=0; $i<count($bitSelector); $i++)
		{
			if(($matchIndex & $bitSelector[$i]) == $bitSelector[$i])
			{
				$outputString .= ($gaugeArray[$i].'+ ');
			}
		}
		$outputString = trim($outputString, '+ ');
		$outputString .= ' = '.$bestMatch.' which is most close to desired value '.$desiredValue;
		echo $outputString;
	}
	else
	{
		echo 'No gauge conbination can give that desired value.';
	}
	
}
?>

现在$ possibleCombinations包含所有可能的值。您需要选择最接近且更小或等于所需值的那个。