2016-10-18 1 views
-1

En utilisant une équation aléatoire (avec plus et multiplier), calculez le résultat.Calculer l'équation sous forme de chaîne

Par exemple, étant donné, "5 + 3 * 4 * 2 + 1", retour 30.

Ce fut une question qui m'a été donné une interview à la programmation (il y a un an) et on m'a dit de le faire au moins 0 (n) fois.

J'ai essayé de le faire en python.

Répondre

2

En supposant que vous ne vouliez pas utiliser eval, vous pouvez essayer de le faire en ligne.

Une bonne technique de résolution de problèmes pour ce genre de question est d'écrire ce que vous voulez arriver.

Si vous regardez cet article par article, vous remarquerez que lorsque nous avons addition, vous pouvez en toute sécurité ajouter tous les résultats précédents ensemble. Avec la multiplication, nous devons toujours attendre le prochain article.

def strToCal(strings): 
    first = 0; 
    second = 0; 

    list1 = [] 
    list1 = strings.split() 

    mult = False 

    for i in list1: 

     if i == "+": 
      first += second 
      second = 0 
      mult = False 
     elif i == "*": 
      mult = True 
     else: 
      if mult: 
       second *= int(i) 
      else: 
       second = int(i) 

    return (first + second) 


print strToCal("5 * 34 * 75 * 2 + 1") 
2

Fonction intégrée eval()pas recommandé comme go-to, mais est plutôt très utile dans ce cas particulier:

string = "5 + 3 * 4 * 2 + 1" 
print (eval(string)) 
# 30 

Bien qu'il existe toute une quantité d'effets secondaires et les risques en utilisant eval(). Donc, ne pas utiliser assez souvent.
un moyen très utile serait d'extraire les opérateurs et les opérandes séparément, puis de faire l'arithmétique désirée.

operands = [int(x) for x in string if x.isdigit()] # not using re as this is faster 
# [5, 3, 4, 2, 1] 

operators = re.findall(r"[^\d\s]", string) 
# ['+', '*', '*', '+'] 

Vous pouvez maintenant appliquer les opérateurs aux deux opérandes correspondants dans une fonction. Assurez-vous de garder une bonne convention arithmétique (* devrait venir avant +)

+1

en utilisant 'ast.literal_eval()' est un moyen plus sûr de 'eval' –

+0

est-il un moyen de voir le code derrière eval? – Shaw

+0

@Shaw vous pouvez vérifier un peu du code à l'intérieur avec 'import inspect; importer ast; print (inspect.getsource (ast.literal_eval)) ' – Nf4r

0

Vous pouvez écrire votre expression sous la forme

expression = term + term + ... + term

et un terme

term = value * value * ... * value

Ceci est une information l façon de spécifier la grammaire pour votre expression. Vous devez reconnaître que l'évaluation d'une expression de cette forme ne nécessite pas un analyseur de descente récursif qui simplifie grandement les choses.

Une technique de solution O (N) consiste ensuite à évaluer chaque term de gauche à droite; appeler une fonction sur chaque étape qui évalue un term particulier.

0

Une autre solution consisterait à convertir votre expression mathématique (infixe) en postfix, ce qui est facile à évaluer en utilisant une pile. Si vous êtes intéressé voici un beau site qui décrit la conversion, ainsi que l'évaluation/calcuation d'une expression postfix:

http://interactivepython.org/runestone/static/pythonds/BasicDS/InfixPrefixandPostfixExpressions.html

complexité informatique pour convertir infix à Postfix et évaluer l'expression serait d'environ O (3 * n) qui est en fait toujours O (n).