[ PsihoXXX @ 08.08.2014. 22:43 ] @
Prvo da pozdravim sve clanove na forumu,posto mi je ovo prvi post.

Nemam neko veliko iskustvo u programiranju,pokusao sam da napravim jednostavnu Windows Store aplikaciju koja predstavlja digitron.

Problem na koji sam naisao jeste bio kako da iz nekog TextBox-a koji ce mi sadrzati string tipa " 2+5*6" izracunam zaista taj izraz. Pregledao sam puno clanaka na internetu i video da je neko najjednostavnije resenje sledeca linija koda:

var result = new DataTable().Compute(ceoUnos, null); // ceoUnos je string koji racunam

E sada problem jeste sto ja ne mogu da ukljucim biblioteku System.Data,jer ona ne postoji,a upravo ona mi treba za DataTable().

Naravno pokusao sam i ovo da resim,i video sam da probelm moze biti verzija .NET Framework-a ,i da se savetuje da bude 4.0 za ovo. Moja nije bila 4.0 ,ali sam kreirao novi projekat i izabrao 4.0 verziju,medjutim i dalje ne mogu ukljuciti System.Data. Kada u solution explorer-u kliknem na projekat-properties opcija target framework nije oznacena. VS2012 je u pitanju.

Ako mi neko moze pomoci oko ovoga bio bi zahvalan.
[ dusans @ 09.08.2014. 09:16 ] @
Koliko vidim, za Metro aplikacije nije moguće koristiti System.Data

Ako ti treba ovakvo izračunavanje izraza bez promenljivih i funkcija, algoritam nije komplikovan.
Samo mi reci da li ti trebaju zagrade u izrazu ili ne, pošto je algoritam malo prostiji bez zagrada,
pa ću da ga onda opišem ovde ako ti to odgovara.
I naravno, napiši koji operatori ti trebaju +, -, *, ...
[ PsihoXXX @ 09.08.2014. 11:19 ] @
Da,sad vidim da System.Data mogu da ukljucim u konzolnoj aplikaciji.

Ne trebaju zagrade,a koristim najjednostavnije operatore,znaci +,-,*,/.

Ja sam isto razmišljao da sam nekako to izvučem,ali nisam siguran kako bi logiku oko operatora primenio.
[ dusans @ 09.08.2014. 12:37 ] @
Onda ovako ako ne trebaju zagrade:

Ideš od grupa operatora manjeg prioriteta ka operatorima većeg prioriteta, dakle +, - pa zatim *, /
Imaš jednu funkciju koja prima izraz kao string i rekurzivna je, nazovimo je Eval.

U funkciji Eval prvo tražiš prvu pojavu + ili -
Ako si našao + ili -, deliš string na dva dela, levo od operatora i desno od operatora (isključujući operator u oba slucaja),
zatim vraćaš vrednost return Eval(levo) + Eval(desno) odnosno return Eval(levo) - Eval(desno) zavisno od operatora.

Ako nisi našao ni + ni -, onda tražiš prvu pojavu * ili /
Ako si našao * ili /, deliš string na dva dela, levo od operatora i desno od operatora (isključujući operator u oba slucaja),
zatim vraćaš vrednost return Eval(levo) * Eval(desno) odnosno return Eval(levo) / Eval(desno) zavisno od operatora.
Dakle, isto kao i u slučaju + i -

Ako nisi našao ni jedan operator onda se verovatno radi o konstanti (broju).
Ako je string izraza prazan onda vrati 0 da bi mogao da podržiš unarni minus i plus.
Ako string izraza nije prazan, parsiraj ga u broj i vrati taj broj sa return.

Neke osnovne provere i radnje koje bi trebao da izvršiš nad izrazom pre računanja jesu:
- Izraz može da počne samo sa cifrom, + ili -
- Izraz ne sme da se završi sa operatorom
- Iz izraza bi trebalo izbaciti sve blanko (space) karaktere ukoliko ih ima
...

Za sada toliko, nemam više vremena sada, pitaj ako nešto nije jasno pa ću ti odgovoriti.
Pozdrav!

[ PsihoXXX @ 10.08.2014. 13:10 ] @
Nije mi jasno skroz kako da izvučem brojeve. Naprimer neki šablon te klase Eval bi bio sledeći ako sam dobro razumeo:

Sad vidim da ne pravi lepo razmake,pa evo ovde. http://pastebin.com/4xWssfff

private ? Eval(ref string ceoUnos)
{
for(int i = 0; i < ceoUnos.Length; i++)
{
if (ceoUnos == '+')
{
string[] deo = ceoUnos.Split(new char[] { '+' }, 2);
return Eval(ref deo[0]) + Eval(ref deo[1]);
}
else if(...) {...}
}
}



E sad ovo i moze proci sa + operatorom. Kada vracam 2 dela Eval funkciji,ako je u pitanju recimo operator * ne mogu mnoziti 2 stringa. A opet ne mogu ni izvlaciti brojeve jer u tom slučaju ako krenem da ih izvlačim možda ima još xxx operatora.

Ako može malo pojašnjenje bio bi zahvalan.
[ dusans @ 10.08.2014. 16:59 ] @
Algoritam je onakav kakav sam i opisao, dakle, ne vraćaju se stringovi već brojevi (npr decimal) i relativno je lako implementirati ga i razumeti ga...
Prvobitno nisam stavio kod, ne bi bilo interesantno, a i nisam imao vremena da ga napišem.
Sada sam imao vremena pa sam napisao dve varijante Eval funkcije, Eval2 funkicja je ono što tebi verovatno treba, onako kako bi čovek računao...

Code:

        public static decimal Eval1(string Expression)
        {
            // Check empty
            if (string.IsNullOrEmpty(Expression)) return 0;
        
            // Match + or - operator (add or subtract)
            var FIA = Expression.IndexOf('+') ;
            var FIS = Expression.IndexOf('-');
            if (FIA >= 0 && (FIS < 0 || FIS > FIA))
            {
                var Left = Expression.Substring(0, FIA);
                var Right = Expression.Substring(FIA + 1);
                return Eval1(Left) + Eval1(Right);
            }
            if (FIS >= 0)
            {
                var Left = Expression.Substring(0, FIS);
                var Right = Expression.Substring(FIS + 1);
                return Eval1(Left) - Eval1(Right);
            }

            // Match * or / operator (mutiply or divide)
            var FIM = Expression.IndexOf('*');
            var FID = Expression.IndexOf('/');
            if (FIM >= 0 && (FID < 0 || FID > FIM))
            {
                var Left = Expression.Substring(0, FIM);
                var Right = Expression.Substring(FIM + 1);
                return Eval1(Left) * Eval1(Right);
            }
            if (FID >= 0)
            {
                var Left = Expression.Substring(0, FID);
                var Right = Expression.Substring(FID + 1);
                return Eval1(Left) / Eval1(Right);
            }

            // Decimal constant
            return decimal.Parse(Expression);
        }

        public static decimal Eval2(string Expression)
        {
            // Check empty
            if (string.IsNullOrEmpty(Expression)) return 0;
        
            // Match + or - operator (add or subtract)
            var FIA = Expression.LastIndexOf('+') ;
            var FIS = Expression.LastIndexOf('-');
            if (FIA >= 0 && FIA > FIS)
            {
                var Left = Expression.Substring(0, FIA);
                var Right = Expression.Substring(FIA + 1);
                return Eval2(Left) + Eval2(Right);
            }
            if (FIS >= 0)
            {
                var Left = Expression.Substring(0, FIS);
                var Right = Expression.Substring(FIS + 1);
                return Eval2(Left) - Eval2(Right);
            }

            // Match * or / operator (mutiply or divide)
            var FIM = Expression.LastIndexOf('*');
            var FID = Expression.LastIndexOf('/');
            if (FIM >= 0 && FIM > FID)
            {
                var Left = Expression.Substring(0, FIM);
                var Right = Expression.Substring(FIM + 1);
                return Eval2(Left) * Eval2(Right);
            }
            if (FID >= 0)
            {
                var Left = Expression.Substring(0, FID);
                var Right = Expression.Substring(FID + 1);
                return Eval2(Left) / Eval2(Right);
            }

            // Decimal constant
            return decimal.Parse(Expression);
        }
[ PsihoXXX @ 10.08.2014. 22:21 ] @
Hvala puno,u prvu ruku mi nije bilo najjasnije baš kako da izvedem.

Sad kad vidim rešenje jeste zaista jednostavno,ali vukao sam na pogrešnu stranu jer nisam imao vraćanje broja na kraju i način sa sekvencijalnim prolazom kroz string i proverama if-else if kakve sam naveo bi me doveo to toga da string tipa "2*3+6" može razdvojiti na 2 stringa "2" i "3+6" što svakako ne valja.

Znam kako je nov sam na forumu,ali svakako nisam tražio gotovo rešenje jer znam da ima mnogo takvih slučajeva,samo kao što sam rekao nemam neko iskustvo pa ne zamerite. Planiram da ostanem na forumu,nadam se i da ću ja nekom moći pomoći. Pozdrav.