Rozpoznanie funkcie - drevorubač

Kód rozpoznáva funkciu v tvare napr.: 2 * x * 7 * pi() drevorubačským spôsobom.

Namiesto * môže byť /,^,+,- v ľubovoľnej obmene (priorita operátorov). Namiesto pi() môže byť sin(x), cos(x) a sqrt(x).

Najskôr odstránim medzery, potom nájdem operátory a operandy, uložím ich do premenných, určím prioritu a podľa operátorov vykonám výpočet. Na vstupe je samotná funkcia a interval s inkrementom, z ktorého dosadzujeme x v iterácii.

<?php

function scitaj($c1, $o, $c2) {
	switch ($o) {
		case "+":return $c1+$c2;
		case "-":return $c1-$c2;
		case "*":return $c1*$c2;
		case "/":return $c1/$c2;
		case "^":return $c1^$c2;
	}
}

function vyhodnot($str, $min, $max, $krok) {
	$str = str_replace(" ","",$str);
	$prvy=$posledny=0;
	if ($str[0]=="-") {$prvy++; $posledny++; }
	for ($i=$prvy; $i<strlen($str); $i++) {
		if (is_numeric($str[$i])) $posledny=$i;
		else break;
	}
	$cislo1= intval(substr($str, $prvy, $posledny+1));
	if ($str[0]=="-") $cislo1*=-1;
	$prvy=$posledny;
	$o1=$str[$prvy+1];
	$o2=$str[$prvy+3];
	$prvy += 4;
	for ($i=$prvy; $i<strlen($str);$i++) {
		if (is_numeric($str[$i])) $posledny=$i;
		else break;
	}
	$cislo2= intval(substr($str, $prvy, $posledny));
	$prvy=$posledny;
	$o3=$str[$prvy+1];
	$prvy += 2;
	
	echo "f(x)= $str<br>";	
	
	for ($x=$min; $x<$max; $x+=$krok) {
		
		$c1=$cislo1;
		$c2=$cislo2;
		
		if ($str[$prvy]=="s"){
			if ($str[$prvy+1]=="i") $gf=sin($x);
			else $gf=sqrt($x);
		}
		elseif ($str[$prvy]=="c") $gf=cos($x);
		else $gf=pi();
		
		$vp=array("/","^","*");
		$np=array("+","-");
		
		//echo "[$c1][$o1][$x][$o2][$c2][$o3][$str[$prvy]]<br>";		
		
		if(in_array($o1,$np) && in_array($o2,$vp) && in_array($o3,$np)) {
			//echo ":1:";
			$c1=scitaj($c1,$o1,scitaj($x,$o2,$c2));
			$c1=scitaj($c1,$o3,$gf);
		}
		elseif(in_array($o1,$np) && in_array($o2,$np) && in_array($o3,$vp)) {
			//echo ":2:";
			$c2=scitaj($x,$o2,scitaj($c2,$o3,$gf));
			$c1=scitaj($c1,$o1,$c2);	
		}
		elseif(in_array($o1,$vp) && in_array($o2,$np) && in_array($o3,$vp)) {
			//echo ":3:";
			$c1=scitaj($c1,$o1,$x);
			$c2=scitaj($c2,$o3,$gf);
			$c1=scitaj($c1,$o2,$c2);	
		}
		elseif(in_array($o1,$np) && in_array($o2,$vp) && in_array($o3,$vp)) {
			//echo ":4:";
			$c2=scitaj($x,$o2,scitaj($c2,$o3,$gf));		
			$c1=scitaj($c1,$o1,$c2);	
		} else {
			//echo ":5:";
			$c1=scitaj($c1,$o1,$x);
			$c1=scitaj($c1,$o2,$c2);
			$c1=scitaj($c1,$o3,$gf);
		}
		echo "f($x) = $c1<br>";
	}
}

echo       2 * 5 * 7- pi(); echo "<br>";
vyhodnot("2 * x * 7 -  pi",1,20,1);
?>

Výstup

66.8584073464
f(x)= 2*x*7-pi
f(1) = 10.8584073464
f(2) = 24.8584073464
f(3) = 38.8584073464
f(4) = 52.8584073464
f(5) = 66.8584073464
f(6) = 80.8584073464
f(7) = 94.8584073464
f(8) = 108.858407346
f(9) = 122.858407346
f(10) = 136.858407346
f(11) = 150.858407346
f(12) = 164.858407346
f(13) = 178.858407346
f(14) = 192.858407346
f(15) = 206.858407346
f(16) = 220.858407346
f(17) = 234.858407346
f(18) = 248.858407346
f(19) = 262.858407346