Hned při zadání úkolu jsem měl jasno - chci kalkulačku, která bude jako dnešní moderní kalkulačky. Napíšete na display celý příklad, stisknete rovná se a vypadne výsledek. Když jsem měl vše připravené k práci s příkladem, zjistil jsem, že není žádná rozumná fce v PHP (nebo se mi ji jen nepovedlo nalézt), která by přijala string a ve výsledku by vyplivla správný výsledek, jediná taková funkce je eval
mixed eval(string $code_str)
s tou je bohužel problém, že nedělá žádné přednosti mezi násobením a sčítáním, takže výsledek byl většinou úplně špatně.
Tím pádem jsem měl jen jednu možnost, jak toto vyřešit - udělat si vlastní parser, který projede string, vybere z něj všechny čísla, uloží je do array a pak pojede znaménko po znaménku v určitém pořadí. Funkce která parsuje string je zde:
function parser($string)
{
$temp1=StrTr($string, "+-*/", " "); //změna znamének za mezery
$vsechny_cisla=explode(" ", $temp1); //vypsání jednotlivých čísel do array
if($pozice_znamenka=StrPos($string,"/"))
{
$index=pozice($pozice_znamenka,$vsechny_cisla);
$temp2=$vsechny_cisla[$index-1]/$vsechny_cisla[$index];
$string=Str_Replace($vsechny_cisla[$index-1]."/".$vsechny_cisla[$index], $temp2, $string);
}
else if($pozice_znamenka=StrPos($string,"*"))
{
$index=pozice($pozice_znamenka,$vsechny_cisla);
$temp2=$vsechny_cisla[$index-1]*$vsechny_cisla[$index];
$string=Str_Replace($vsechny_cisla[$index-1]."*".$vsechny_cisla[$index], $temp2, $string);
}
else if($pozice_znamenka=StrPos($string,"-"))
{
$index=pozice($pozice_znamenka,$vsechny_cisla);
$temp2=$vsechny_cisla[$index-1]-$vsechny_cisla[$index];
$string=Str_Replace($vsechny_cisla[$index-1]."-".$vsechny_cisla[$index], $temp2, $string);
}
else if($pozice_znamenka=StrPos($string,"+"))
{
$index=pozice($pozice_znamenka,$vsechny_cisla);
$temp2=$vsechny_cisla[$index-1]+$vsechny_cisla[$index];
$string=Str_Replace($vsechny_cisla[$index-1]."+".$vsechny_cisla[$index], $temp2, $string);
}
if(StrPos($string,"/") || StrPos($string,"*") || StrPos($string,"+") || StrPos($string,"-"))
{
$string=parser($string); //pokud existuje ve stringu další znaménko, fce vyvolá sama sebe
}
return $string;
}Myslím, že není co vysvětlovat, funkce je udělaná snad nejsnáž jak to jen jde. Druhá potřebná funkce je pozice($pozice_znamenka,$vsechny_cisla), která vrací index čísla, které se nachází za aktuální znaménkem. Tím pádem po odečtení 1 získám index čísla před znaménkem a mohu mezi těmito dvěma čísli provést výpočet. Tato funkce se skládá pouze z jednoho cyklu, pokud nevěříte, přesvědčte se sami :-) :
function pozice($pozice_znamenka,$vsechny_cisla)
{
$index=0;
while($delka_pred_znamenkem<=$pozice_znamenka)
{
$delka_pred_znamenkem += strlen($vsechny_cisla[$index]);
if($index!=0)
{
$delka_pred_znamenkem++;
}
$index++;
}
return ($index-1);
}Toto je všechen důležitý kód mého "domácího úkolu", výsledek si můžete prohlédnout zde. Časem ve chvílích nudy přidám pár dalších funkcí a popřípadě opravím aktuální nedostatky dalším ošetřením.




