2014-05-25 6 views
0

Je fais une application de calculatrice pour me mettre au défi et j'ai besoin d'un coup de main dans la planification de ma logique. Chose est, l'équation est dans une seule chaîne et je dois en quelque sorte comprendre les numéros sur les côtés gauche et droit d'un opérateur que j'évalue (il y a un ordre des opérations). Le défi est qu'il y a aussi des opérateurs unaires, ce qui signifie que je ne peux pas simplement supposer qu'un nombre (d'un côté ou de l'autre) est délimité par un autre opérateur. Par exemple - J'essaie d'évaluer quelque chose comme 5 + 5^-2-3. L'ordre des opérations signifie que je me concentre sur le^premier, donc j'ai besoin d'obtenir le 5 et -2, les comprendre, puis mettre à jour l'équation à 5 + 25-3 puis évaluer le reste des opérations dans l'ordre.Calculatrice Logique

Des idées? Merci.

Répondre

2

Il existe un algorithme célèbre pour résoudre ce problème exact. Il s'appelle le Shunting Yard Algorithm

+0

Ouais, je l'ai vu un avant. Notation polonaise inversée? C'est une bonne idée, mais malheureusement, ce serait plutôt difficile à mettre en œuvre, étant donné que tout est transmis en une seule chaîne. :/ – M2065

+0

L'algorithme de triage de triage est destiné à la conversion de l'infixe (c'est-à-dire 1 + 2) en RPN. – mclaassen

+0

@ M2065 Ne pas rejeter cela trop vite! L'algo de Shunting-yard peut être complété et amélioré pour gérer la précédence et l'associativité.C'est l'algorithme le plus puissant pour cela, à part de faire un parser-> syntax-tree-> tree-eval. –

0

Vous pouvez utiliser des expressions régulières pour cela. Par exemple

/(\d+)([\+\*])(\d+)/g 

correspond à n'importe quel groupe de chiffres de chaque côté d'un signe plus ou de multiplication. Appliqué à

"47+65" 

donnerait 3 groupes, le premier étant « 47 », la seconde étant « + » et la troisième étant « 65 ».

De toute évidence, vous devez prendre en compte tous les opérateurs possibles. Dans une équation plus complexe, vous devez obtenir toutes les correspondances et effectuer une vérification conditionnelle pour déterminer quel groupe appliquer en premier. Vous devrez peut-être aussi considérer entre parenthèses - par exemple affectent-elles l'ordre de fonctionnement - et inclure dans le regex

Modifier: Et juste pour le plaisir (et à cause du vote vers le bas), j'ai créer un exemple simple here (plus, moins, multiplier et diviser les opérateurs uniquement, sans espace entre les nombres et les opérateurs)

Modifier 2:Updated fiddle (permet à plusieurs opérateurs dans l'expression et les nombres décimaux)

Edit 3:Updated fiddle (y compris l'opérateur d'alimentation - 2^3 = 8)

Edit 4:Updated fiddle (tient parenthèses de compte, l'espace blanc, de division par zéro)

+0

Votre solution ne gère que le cas le plus trivial de 2 numéros avec un seul opérateur. – mclaassen

+0

Ceci aide à analyser les jetons de la chaîne, mais le processus d'évaluation de l'ordre des opérations et de traitement des parenthèses n'est pas trivial. – mclaassen

+0

@mclassen, je sais, son exemple simple pour montrer la logique (comme demandé par OP), pas une solution complète –

0

d'abord une structure arborescente vient à l'esprit. Mais si vous voulez très simple, en fonction de la langue que je créerais un tableau

[[5,number],[+,operator1],[5,number],[^,operator3],[-2,number],[-,operator1],[3,number]]

puis passer par que pour chaque opérateur:

1) [[5,number],[+,operator1],[0.04,number],[-,operator1],[3,number]] 
2) [[2.04,number]]