Quand j'ai vu le titre de cette question fermée , j'ai pensé que cela ressemblait à un défi de golf de code intéressant. Alors laissez-moi le présenter comme tel:
Défi:
Écrivez un programme, une expression ou un sous-programme qui, étant donné une expression arithmétique en notation infixe , comme 1 + 2, génère la même expression en notation postfixe , c'est-à-dire 1 2 +.
(Remarque: un défi similaire a été publié plus tôt en janvier. Cependant, je pense que les deux tâches sont suffisamment différentes en détail pour justifier ce défi distinct. De plus, je n'ai remarqué l'autre fil après avoir tapé tout ci-dessous, et je préfère pas simplement jeter le tout.)
Contribution:
L'entrée se compose d'une expression arithmétique infixée valide consistant en nombres (entiers non négatifs représentés comme des séquences d'un ou plusieurs chiffres décimaux), équilibré entre parenthèses pour indiquer une sous - expression regroupés, et les quatre binaires infix opérateurs + , -, *et /. N'importe lequel d'entre eux peut être séparé (et l'expression entière entourée) par un nombre arbitraire de caractères d'espace, qui doivent être ignorés. 1
Pour ceux qui aiment les grammaires formelles, voici une grammaire simple de type BNF qui définit les entrées valides. Pour des raisons de concision et de clarté, la grammaire n'inclut pas les espaces facultatifs, qui peuvent apparaître entre deux jetons (autres que les chiffres d'un nombre):
expression := number | subexpression | expression operator expression
subexpression := "(" expression ")"
operator := "+" | "-" | "*" | "/"
number := digit | digit number
digit := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
1 Le seul cas où la présence d'espaces peut affecter l'analyse est lorsqu'ils séparent deux nombres consécutifs; cependant, puisque deux nombres non séparés par un opérateur ne peuvent pas apparaître dans une expression d'infixe valide, ce cas ne peut jamais se produire dans une entrée valide.
Sortie:
La sortie doit être une expression suffixe équivalente à l'entrée. L'expression de sortie doit contenir que des nombres et les opérateurs, avec un seul caractère d'espace entre chaque paire de jetons adjacents, comme dans la grammaire ci - après (qui ne comprennent les espaces) 2 :
expression := number | expression sp expression sp operator
operator := "+" | "-" | "*" | "/"
number := digit | digit number
digit := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
sp := " "
2 Encore pour plus de simplicité, la numberproduction dans cette grammaire admet des nombres avec des zéros en tête, même s'ils sont interdits dans la sortie par les règles ci-dessous.
Priorité des opérateurs:
En l'absence de parenthèses, les règles de priorité suivantes s'appliquent:
- Les opérateurs
*et/ont une priorité plus élevée que+et-. - Les opérateurs
*et/ont une priorité égale les uns aux autres. - Les opérateurs
+et-ont une priorité égale les uns aux autres. - Tous les opérateurs sont associatifs à gauche.
Par exemple, les deux expressions suivantes sont équivalentes:
1 + 2 / 3 * 4 - 5 + 6 * 7
((1 + ((2 / 3) * 4)) - 5) + (6 * 7)
et ils devraient tous deux produire la sortie suivante:
1 2 3 / 4 * + 5 - 6 7 * +
(Ce sont les mêmes règles de priorité que dans le langage C et dans la plupart des langues qui en dérivent. Elles ressemblent probablement aux règles qui vous ont été enseignées au primaire, sauf peut-être pour la priorité relative de *et /.)
Règles diverses:
Si la solution donnée est une expression ou un sous-programme, l'entrée doit être fournie et la sortie renvoyée sous la forme d'une chaîne unique. Si la solution est un programme complet, elle doit lire une ligne contenant l'expression infixe de l'entrée standard et imprimer une ligne contenant la version postfixe sur la sortie standard.
Les nombres dans l'entrée peuvent inclure des zéros non significatifs. Les nombres dans la sortie ne doivent pas avoir de zéros en tête (à l'exception du nombre 0, qui doit être sorti comme
0).Vous n'êtes pas censé évaluer ou optimiser l'expression en aucune façon. En particulier, vous ne devez pas supposer que les opérateurs satisfont nécessairement toutes les identités associatives, commutatives ou autres identités algébriques. Autrement dit, vous ne devez pas supposer que, par exemple,
1 + 2est égal2 + 1ou1 + (2 + 3)égal à(1 + 2) + 3.Vous pouvez supposer que les nombres en entrée ne dépassent pas 2 31 - 1 = 2147483647.
Ces règles visent à garantir que la sortie correcte est définie de manière unique par l'entrée.
Exemples:
Voici quelques expressions d'entrée valides et les sorties correspondantes, présentées sous la forme "input" -> "output":
"1" -> "1"
"1 + 2" -> "1 2 +"
" 001 + 02 " -> "1 2 +"
"(((((1))) + (2)))" -> "1 2 +"
"1+2" -> "1 2 +"
"1 + 2 + 3" -> "1 2 + 3 +"
"1 + (2 + 3)" -> "1 2 3 + +"
"1 + 2 * 3" -> "1 2 3 * +"
"1 / 2 * 3" -> "1 2 / 3 *"
"0102 + 0000" -> "102 0 +"
"0-1+(2-3)*4-5*(6-(7+8)/9+10)" -> "0 1 - 2 3 - 4 * + 5 6 7 8 + 9 / - 10 + * -"
(Au moins, j'espère que tout cela est correct; j'ai fait la conversion à la main, donc des erreurs auraient pu se glisser.)
Juste pour être clair, les entrées suivantes sont toutes invalides; il ne pas d' importance ce que votre solution ne se les donne (bien que, bien sûr, par exemple , renvoyer un message d'erreur est plus agréable que, par exemple, la consommation d' une quantité infinie de mémoire):
""
"x"
"1 2"
"1 + + 2"
"-1"
"3.141592653589793"
"10,000,000,001"
"(1 + 2"
"(1 + 2)) * (3 / (4)"
1 2 3 4 + *?
1 2 3 4 +signifie «1 + 2 + 3 + 4».