PHP:如何按指数对字符串“多项式方程”进行排序


PHP: How to sort a string Polymonial Equation by exponent

我在php:中有这个字符串

$equation = "-29x^3+1x^4-16x^1-9x^-1-6x^-3-6x^-4+2x^2-18-3x^6";

但我想按指数排序,正确的结果是:

$result = "-3x^6+1x^4-29x^3+2x^2-16x^1-9x^-1-6x^-3-6x^-4-18";

我该怎么做?

我已经尝试过usort,natort,但不工作

$pattern = '/(?:[+-]?'d+(?:x(?:'^[+-]?'d+))?)?'K/';
$equation = "-29x^3+1x^4-16x^1-9x^-1-6x^-3-6x^-4+2x^2-18-3x^6";
//  Split an equation for items and remove empty result
$result = array_filter(preg_split($pattern, $equation));
// sort descending of exponent 
usort($result, function($a, $b) 
                 { 
                   list(,$a) = explode('^', $a);
                   if($a === NULL) return 1;
                   list(,$b) = explode('^', $b);
                   if($b === NULL) return -1;
                   return $b-$a;
                 });
// Join to result string
echo implode('', $result); // -3x^6+1x^4-29x^3+2x^2-16x^1-9x^-1-6x^-3-6x^-4-18

在此处测试

使用preg_match_allusortpreg_replace函数的解决方案:

$equation = "-29x^3+1x^4-16x^1-9x^-1-6x^-3-6x^-4+2x^2-18-3x^6";
preg_match_all("/[-+]?'d+?x'^[+-]?'d+?|[+-]'d+?(?=[+-])/", $equation, $matches);
usort($matches[0], function ($a, $b){
    return (int) preg_replace("/^.*'^/", "", $b)
           - (int) preg_replace("/^.*'^/", "", $a);
});
$result = implode("", $matches[0]);
print_r($result);  // "-3x^6+1x^4-29x^3+2x^2-16x^1-9x^-1-6x^-3-6x^-4-18"

你可以这样做:

$equation = '-29x^3+1x^4-16x^1-9x^-1-6x^-3-6x^-4+2x^2-18-3x^6';
$result = '';
if (preg_match_all('~[+-]?'d*(?:x(?:'^([+-]?'d+))?)?~', $equation, $matches)) {
    foreach ($matches[0] as $k=>$v)
        if (substr($v, -1)=='x') $matches[1][$k] = 1;
    arsort($matches[1]); // sort the keys by exponent values
    foreach ($matches[1] as $k=>$v)
        $result .= $matches[0][$k];
}
echo $result, PHP_EOL;

使用preg_split:的其他方式

$parts = preg_split('~'b(?=[-+])~', $equation);
if (!in_array(substr($parts[0], 0, 1), ['-','+'])) $parts[0] = '+' . $parts[0];
$assoc = [];
foreach ($parts as $v) {
    $tmp = explode('^', $v);
    if (isset($tmp[1])) $assoc[$v] = $tmp[1];
    elseif (strpos($v, 'x')!==false) $assoc[$v] = 1;
    else $assoc[$v] = '';
}
arsort($assoc);
$result = implode('', array_keys($assoc));