PHP:如何用指数对字符串Polymonial Equation进行排序

时间:2016-07-23 20:54:40

标签: php regex

我在php中有这个字符串:

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

但是我想用exponent对它进行排序,正确的结果将是:

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

我是怎么做到的?

我尝试了usort,natsort但不起作用

3 个答案:

答案 0 :(得分:3)

$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

<强> test it here

答案 1 :(得分:2)

你可以这样做:

$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));

答案 2 :(得分:2)

使用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"