Podgląd pliku: / jacekk.info / rpn.phps
<?php
/**************************************************
* Kalkulator RPN *
**************************************************
* Wersja: 1.0 *
* Autor: Jacek Kowalski (http://jacekk.info) *
* *
* Strona WWW: http://jacekk.info/scripts/rpn *
* *
* Utwór rozprowadzany na licencji *
* http://creativecommons.org/licenses/by-nc/2.5/ *
**************************************************/
/* Kodowanie znaków UTF-8 */
function test($wyr) {
if(substr_count($in, '(')!==substr_count($in, ')')) {
return FALSE;
}
return trim($wyr, '+-*/^ 0123456789.,()')==='';
}
$test = test($_GET['wyrazenie']);
if(!$_GET['wyrazenie'] OR strlen($_GET['wyrazenie'])>60 OR !$test) {
?>
<form action="" method="get">
<?php if(!$test) {echo '<p><strong>Błąd w wyrażeniu</strong></p>'.$test."\n";} ?>
<input type="text" name="wyrazenie"/> <input type="submit" value="Oblicz"/>
<hr/>
<ul>
<li>Dostępne operatory: + - * / ^ ( )</li>
<?php if(strlen($_GET['wyrazenie'])>100) {echo '<li><strong>Maksymalna ilość znaków: 60</strong></li>'."\n";}
else {echo '<li>Maksymalna ilość znaków: 60</li>'."\n";} ?>
<li>Algorytm: Odwrotna Notacja Polska</li>
<li>Autor: <a href="http://jacekk.info">Jacek Kowalski</a></li>
</ul>
</form>
<?php
die(0);
}
function prior($op) {
$prior = array('+' => 1, '-' => 1, '*' => 2, '/' => 2, '^' => 3);
return $prior[$op];
}
function error($msg, $code) {
echo '<p>Błąd '.$code.': '.$msg.'</p>';
}
function onp_1($in) {
$err = array('10' => 'Nierozpoznany znak', '11' => 'Nieprawidłowa ilość nawiasów');
$out = array();
$stos = array();
$tmp = '';
$in = str_split($in);
foreach($in as $v) {
if(is_numeric($v) OR $v==',' OR $v=='.') {
if($v==',') $v = '.';
$tmp .= $v;
}
elseif($v=='(') {
if(!empty($tmp)) {
$out[] = $tmp;
$tmp = '';
}
array_push($stos, '(');
}
elseif($v==')') {
if(!empty($tmp)) {
$out[] = $tmp;
$tmp = '';
}
while(TRUE) {
$wyr = array_pop($stos);
if($wyr==NULL) {
error($err['11'], 11);
die(11);
}
if($wyr!=='(') {
$out[] = $wyr;
}
else
{
break;
}
}
}
elseif($v=='+' OR $v=='-' OR $v=='*' OR $v=='/') {
$tmp_prior = prior($v);
if(!empty($tmp)) {
$out[] = $tmp;
$tmp = '';
}
while(TRUE) {
$wyr = array_pop($stos);
if($wyr==NULL) {
array_push($stos, $v);
break;
}
elseif(prior($wyr)<$tmp_prior) {
array_push($stos, $wyr, $v);
break;
}
else
{
$out[] = $wyr;
}
}
}
elseif($v=='^') {
if(!empty($tmp)) {
$out[] = $tmp;
$tmp = '';
}
array_push($stos, $v);
}
elseif($v==' ') {
continue;
}
else
{
error($err['10'].': \''.$v.'\', kod: '.ord($v), 10);
}
}
if(!empty($tmp)) {
$out[] = $tmp;
$tmp = '';
}
while(TRUE) {
$wyr = array_pop($stos);
if($wyr==NULL) {
break;
}
else
{
$out[] = $wyr;
}
}
return $out;
}
function onp_2($in) {
$stos = array();
foreach($in as $val) {
if(is_numeric($val)) {
array_push($stos, $val);
}
else
{
$a = array_pop($stos);
$b = array_pop($stos);
switch($val) {
case '+':
array_push($stos, bcadd($b, $a, 10));
break;
case '-':
array_push($stos, bcsub($b, $a, 10));
break;
case '*':
array_push($stos, bcmul($b, $a, 10));
break;
case '/':
array_push($stos, bcdiv($b, $a, 10));
break;
case '^':
array_push($stos, bcpow($b, $a, 10));
break;
default:
error('Nierozpoznany znak: '.$val, 10);
break;
}
}
}
return array_pop($stos);
}
$res1 = onp_1($_GET['wyrazenie']);
$res2 = onp_2($res1);
?>
<form action="" method="get">
<input type="text" name="wyrazenie"/> <input type="submit" value="Oblicz"/>
<hr/>
<pre><?php echo htmlspecialchars($_GET['wyrazenie']).' = '.implode(' ', $res1).' = '.$res2; ?></pre>
<hr/>
<ul>
<li>Dostępne operatory: + - * / ^ ( )</li>
<li>Maksymalna ilość znaków: 60</li>
<li>Algorytm: Odwrotna Notacja Polska</li>
<li>Autor: <a href="http://jacekk.info">Jacek Kowalski</a></li>
</ul>
</form>
Browse Code © 2010 by Jacek Kowalski