Kalkulačka v PHP a javascriptu

Ve škole jsme minulý týden dostali za úkol, udělat primitivní kalkulačku, ve které se "naučíme" používat funkci submit ve formulářích. Tak jsem tento úkol zpracoval poněkud složitěji a rád bych se s ním zde podělil.

ikona kalkulacka-v-php-a-javascriptu

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

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:

fce parser($string)
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 :-) :

fce pozice($pozice_znamenka,$vsechny_cisla)
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.

Komentáře

Nick Příspěvek *
Email
Webové stránky
10 - 6 =
SuGi | MAIL | WEB20:59 19.09.2010
Jak píši v úvodu, je to práce z minulého ročníku školy, takže jsem to již částečně prezentoval. Tu funkci jsem tenkráte tuším zkoušel, ale byl tam nějaký problém a proto jsem ji vyřadil. Bohužel už je to opravdu dávno a nepamatuji se, o co tam přesně šlo.
Jan Turoň | MAIL18:17 19.09.2010
Martine, pokud souhlasíte, rád bych vám dal při hodině trochu prostoru na prezentaci, mohu vám ji započítat i jako referát. Funkce, kterou hledáte, se jmenuje preg_match_all, umožňuje zkrátit váš kód do jediného krátkého příkazu, např.: $math = "5+3*24-6"; preg_match_all("/\d+|[\+\-\*\/]/",$math,$parsed); print_r($parsed); Pokud vás to zaujalo, dejte vědět, mohu o tom něco říct.

Created & Designed by © SuGi 2007-2011 | PWRD BY Veriana (2.0.1450)
Provozovatel nenese žádnou zodpovědnost za škody způsobené používáním tohoto webu