简体   繁体   中英

Randomly sum values, add/subtract them up, until you have a value match php

I have an array of values floats:

$values =array(); // array(6) { [0]=> string(8) "90.00000" [1]=> string(9) "481.93000" [2]=> string(8) "38.11000" [3]=> string(8) "-4.40000" [4]=> string(9) "120.00000" [5]=> string(10) "-120.00000" }

$value_to_be_found = 123.710;

Now e need something that sums them up random until found the $value_to_be_found.

in this case the answer would be:

90.00000

38.11000

-4.40000

There's a bunch of optimization that could be done for this, but I think the source data could be optimized more than the loops, so I'm going to leave it.

Assuming you have this as your input data, specifically an array of float-like values stored as strings, and a search value stored as a float.

$numbers = ['90.00000', '481.93000', '38.11000', '-4.40000', '120.00000', '-120.00000'];
$sum = 123.710;

The below code should work, I've inside

function _searchRecursive($numbers, $sum, &$result, $index = 0, $total = 0, $solution = '')
{
    // The logic in the block following this one works on strings, this converts it back to an integer array
    if ($total === $sum) {
        $result = array_map('intval', explode(' ', trim($solution)));
        return true;
    }

    // This logic is from: https://stackoverflow.com/a/2687982/231316
    if ($index < count($numbers)) {
        return _searchRecursive($numbers, $sum, $result, $index + 1, $total, $solution) or _searchRecursive($numbers, $sum, $result, $index + 1, $total + $numbers[$index], $solution . ' ' . $numbers[$index]);
    }

    return false;
}

function search(array $numbersAsStrings, $sum)
{
    // This is a magic multiple, adjust for your data or else things won't work!
    $multiplier = 100000;

    // Clone the array so that we can return strings later
    $numbersAsInts = $numbersAsStrings;

    // Create an integer array by multiplying each number and casting to int
    foreach ($numbersAsInts as &$number) {
        $number = (int)($number * $multiplier);
    }

    // The previous loop is by reference so it is best to clean up
    unset($number);

    // Scale our search term, too
    $sum = (int)($sum * $multiplier);

    // The recursive search will place the value into this, if found
    $result = null;
    _searchRecursive($numbersAsInts, $sum, $result);

    // Nothing was found
    if (!is_array($result)) {
        return null;
    }

    // Search the original string array and re-match with our int array
    $finalRet = [];
    foreach ($result as $int) {
        foreach ($numbersAsStrings as $string) {
            if ($int === (int)($string * $multiplier)) {
                $finalRet[] = $string;
                break;
            }
        }
    }


    return $finalRet;
}

$result = search($numbers, $sum);

Online version here: https://3v4l.org/Y9T8K

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM