我有一个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);
?>
答案 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包含所有可能的值。您需要选择最接近且更小或等于所需值的那个。