2009-10-01 28 views
8

Używam Objective-C i próbuję ustawić równanie, które jest przechowywane w NSString do oceny i przechowywane w NSInteger.NSString do równania

coś podobnego do poniższego:

equation = [[NSString alloc] initWithString:@"1+5*6"]; 

a następnie ocenia, że ​​aby stać się 31 i przechowywać go w NSInteger. jakieś pomysły, jak to zrobić?

+0

W jakim języku to wyrażenie? Czy jest zawsze stały lub zawiera zmienne? – nall

Odpowiedz

22

Chcesz cudownego, niesamowitego i fantastycznego GCMathParser, dostępnego (ZA DARMO!) Na apptree.net: http://apptree.net/parser.htm Dokładnie o to pytasz, a nawet pozwala ci dokonywać zmiennych podstawień (3x + 42, oceń zx = 7). To nawet ma wsparcie dla funkcji matematycznych, takich jak sin(), cos(), tan(), ich odwrotności, dtor(), log(), ....

edit długi czas później ...

Podczas gdy GCMathParser jest całkiem niezły, ma wadę, której nie można rozszerzyć. Więc jeśli potrzebujesz funkcji, której nie obsługuje natywnie, to jest zbyt źle. Więc postanowiłem coś z tym zrobić, a wymyślił całkowicie rodzimym parser matematyki i oceniającego: http://github.com/davedelong/DDMathParser

+0

dokładnie to, czego potrzebowałem thatnks! –

+0

Słodki! Nigdy wcześniej nie słyszałem o GCMathParser. – NSResponder

+0

To wygląda świetnie. +1 – Daniel

19

Można użyć systemu źródłowe:

NSString *equation = @"1+5*6"; 

// dummy predicate that contains our expression 
NSPredicate *pred = [NSPredicate predicateWithFormat: 
         [equation stringByAppendingString:@" == 42"]]; 
NSExpression *exp = [pred leftExpression]; 
NSNumber *result = [exp expressionValueWithObject:nil context:nil]; 
NSLog(@"%@", result); // logs "31" 
+0

+1 to naprawdę sprytne! Podoba mi się, jak dodać "== 42", aby móc podzielić je na wyrażenia. Czy obsługuje to wszelkie funkcje matematyczne, takie jak sin(), cos(), itp? –

+0

To jest naprawdę interesujące. Nie miałem pojęcia, że ​​możesz to zrobić. Zauważ, że możesz potrzebować rzucić pred jako NSComparisonPredicate (NSExpression * exp = [(NSComparisonPredicate *) pred leftExpression];) aby uniknąć ostrzeżeń kompilatora. –

+2

Niestety, zgodnie z przewodnikiem programowania predykatów, jedynymi obsługiwanymi funkcjami poza podstawową arytmetyką są: suma, liczba, min, maks, średnia, mediana, tryb, stddev, sqrt, log, ln, exp, podłoga, pułap, abs, trunc, losowy, randomn i teraz. Więc chyba nie trygonometria. –

7

muszę to wykorzystać na iPhone ocenić równanie . To prostsze, nie trzeba tworzyć NSPredicate, tylko NSExpression:

NSString *equation = @"floor((19-10)/2)"; 
NSNumber *result = [NSExpression expressionWithFormat:equation]; 
NSLog(@"%@", result); // logs "4" 

A oto docs z kompatybilnymi funkcjami parsowalnym: “BNF Definition of Cocoa Predicates”

kod udostępniony w Gist here

+2

+1 Opcja '+ expressionWithFormat:' została dodana w systemach Mac OS 10.6 i iOS 4.0. –