Je me prépare à un examen où je ne pouvais pas comprendre la conversion de la notation infixe en notation polonaise pour l'expression ci-dessous:
(a–b)/c*(d + e – f / g)
Quelqu'un peut-il dire pas à pas comment l'expression donnée sera convertie en préfixe?
Algorithm ConvertInfixtoPrefix
Purpose: Convert an infix expression into a prefix expression. Begin
// Create operand and operator stacks as empty stacks.
Create OperandStack
Create OperatorStack
// While input expression still remains, read and process the next token.
while( not an empty input expression ) read next token from the input expression
// Test if token is an operand or operator
if ( token is an operand )
// Push operand onto the operand stack.
OperandStack.Push (token)
endif
// If it is a left parentheses or operator of higher precedence than the last, or the stack is empty,
else if ( token is '(' or OperatorStack.IsEmpty() or OperatorHierarchy(token) > OperatorHierarchy(OperatorStack.Top()) )
// Push it to the operator stack
OperatorStack.Push ( token )
endif
else if( token is ')' )
// Continue to pop operator and operand stacks, building
// prefix expressions until left parentheses is found.
// Each prefix expression is Push back onto the operand
// stack as either a left or right operand for the next operator.
while( OperatorStack.Top() not equal '(' )
OperatorStack.Pop(operator)
OperandStack.Pop(RightOperand)
OperandStack.Pop(LeftOperand)
operand = operator + LeftOperand + RightOperand
OperandStack.Push(operand)
endwhile
// Pop the left parthenses from the operator stack.
OperatorStack.Pop(operator)
endif
else if( operator hierarchy of token is less than or equal to hierarchy of top of the operator stack )
// Continue to pop operator and operand stack, building prefix
// expressions until the stack is empty or until an operator at
// the top of the operator stack has a lower hierarchy than that
// of the token.
while( !OperatorStack.IsEmpty() and OperatorHierarchy(token) lessThen Or Equal to OperatorHierarchy(OperatorStack.Top()) )
OperatorStack.Pop(operator)
OperandStack.Pop(RightOperand)
OperandStack.Pop(LeftOperand)
operand = operator + LeftOperand + RightOperand
OperandStack.Push(operand)
endwhile
// Push the lower precedence operator onto the stack
OperatorStack.Push(token)
endif
endwhile
// If the stack is not empty, continue to pop operator and operand stacks building
// prefix expressions until the operator stack is empty.
while( !OperatorStack.IsEmpty() ) OperatorStack.Pop(operator)
OperandStack.Pop(RightOperand)
OperandStack.Pop(LeftOperand)
operand = operator + LeftOperand + RightOperand
OperandStack.Push(operand)
endwhile
// Save the prefix expression at the top of the operand stack followed by popping // the operand stack.
print OperandStack.Top()
OperandStack.Pop()
End
S'il y a quelque chose à propos de quel infixe et préfixe signifie que vous ne comprenez pas très bien, je vous suggère fortement de vous relire cette section de votre manuel Vous ne vous faites pas de faveurs si vous en sortez avec la bonne réponse à ce problème, mais vous ne comprenez toujours pas le concept.
En ce qui concerne les algorithmes, c'est sacrément simple. Vous agissez juste comme un ordinateur vous-même. Commencez par mettre des parenthèses autour de chaque calcul dans l'ordre dans lequel il sera calculé. Ensuite (toujours dans l’ordre du premier calcul à la fin), déplacez simplement l’opérateur devant l’expression située à gauche. Après cela, vous pouvez simplifier en supprimant les parens.
(a–b)/c*(d + e – f / g)
Notation de préfixe (le polissage inversé désigne l'opérateur en dernier, il est difficile de savoir lequel vous voulez dire, mais le principe sera exactement le même)
(/ f g)
(+ d e)
(- (+ d e) (/ f g))
(- a b)
(/ (- a b) c)
(* (/ (- a b) c) (- (+ d e) (/ f g)))
(a–b)/c*(d + e – f / g)
étape 1: (a-b)/c*(d+e- /fg))
étape 2: (a-b)/c*(+de - /fg)
étape 3: (a-b)/c * -+de/fg
Étape 4: -ab/c * -+de/fg
étape 5: /-abc * -+de/fg
étape 6: */-abc-+de/fg
C'est la notation préfixe.
J'ai vu cette méthode sur youtube postant donc ici.
expression infixée donnée: (a – b)/c * (d + e - f/g)
inversez-le:
) g/f-e + d (* c /) b-a (
lire les caractères de gauche à droite.
maintenir une pile pour les opérateurs
1. if character is operand add operand to the output
2. else if character is operator or )
2.1 while operator on top of the stack has lower or **equal** precedence than this character pop
2.2 add the popped character to the output.
Push the character on stack
3. else if character is parenthesis (
3.1 [ same as 2 till you encounter ) . pop ) as well
4. // no element left to read
4.1 pop operators from stack till it is not empty
4.2 add them to the output.
reverse the output and print.
crédits: youtube
(a – b)/c * (d + e - f/g)
rappelez-vous en balayant l'expression du plus à gauche au plus à droite commencer par des termes entre parenthèses suivre la règle QUI EST LE PREMIER PREMIER ....... .... donc (ab) = -bc préfixe (ab) = bc- pour postfixe un autre terme entre parenthèses: (d + e - f/g) = ne déplacez le/d'abord puis plus '+' vient d'abord avant moins soupir '-' (rappelez-vous qu'ils sont au même niveau ..) (d + e - f/g) move/first ( d + e - (/ fg)) = préfixe (d + e - (fg /)) = suffixe suivi de + alors -- ((+ de) - (/ fg)) = préfixe ((de +) - (fg /)) = suffixe
(- (+ de) (/ fg)) = préfixe donc la nouvelle expression est maintenant - + de/fg (1) ((de +) (fg /) -) = postfixe donc la nouvelle expression est maintenant de + fg/- (2)
(a – b)/c * d'où
(a-b)/c * (d + e - f/g) = -bc préfixe [-ab]/c * [- + de/fg] ---> tiré de (1) /c * ne bouge pas encoreso '/' vient d'abord avant '*' car, au même niveau, déplacez '/' à l'extrême droite:// [- ab] c * [- + de/fg] puis déplacez '*' à l'extrême droite
(ab)/c * (d + e - f/g) = bc- pour postfix [ab -]/c * [de + fg/-] ---> tiré de (2) so '/' vient en premier avant '' parce qu'ils se trouvent au même niveau, déplacez '/' à l'extrême gauche: [ab-] c [de + fg /-]/ puis déplacez' 'à l'extrême gauche [ab-] c [de + fg/-] / = supprime les symboles de regroupement = ab - cde + fg/-/* -> Postfix
Cet algorithme vous aidera à mieux comprendre.
Étape 1. Poussez “)” sur STACK et ajoutez “(“ à la fin de la lettre A.).
Étape 2. Scannez A de droite à gauche et répétez les étapes 3 à 6 pour chaque élément de A jusqu’à ce que la PILE soit vide.
Étape 3. Si un opérande est rencontré, ajoutez-le à B.
Étape 4. Si une parenthèse droite est rencontrée Poussez-la sur STACK.
Étape 5. Si un opérateur est rencontré, alors: une. Sortez de manière répétée de STACK et ajoutez à B chaque opérateur (au-dessus de STACK) qui a le même ou une priorité supérieure à celle de l'opérateur . b. Ajouter un opérateur à STACK.
Étape 6. Si la parenthèse laissée est encaissée, alors une. Sortez à plusieurs reprises de la pile et ajoutez à B (chaque opérateur au-dessus de la pile jusqu'à ce qu'une parenthèse gauche soit rencontrée) b. Supprimez la parenthèse gauche.
Étape 7. Quitter
simple recherche google est venu avec this . Je doute que quiconque puisse expliquer cela plus simplement. Mais je suppose qu'après un montage, je peux essayer de faire avancer les concepts afin que vous puissiez répondre à votre propre question.
Indice:
Étudiez pour un examen, difficile, vous devez. Je te prédis, la note devient élevée, je fais: D
Explication:
Tout dépend de la façon dont les opérations sont associées aux opérandes. chaque type de notation a ses propres règles. Il vous suffit de décomposer et de vous souvenir de ces règles. Si je vous disais que j'ai écrit (2 * 2)/3 comme [* /] (2,2,3), tout ce que vous avez à faire est d'apprendre à transformer cette dernière notation en une précédente.
Ma notation personnalisée dit que prendre les deux premiers opérandes et les multiplier, puis que l'opérande résultant devrait être divisé par le troisième. Trouver ? Ils essaient de vous apprendre trois choses.
Infix à PostFix en utilisant Stack:
Example: Infix--> P-Q*R^S/T+U *V
Postfix --> PQRS^*T/-UV
Rules:
Operand ---> Add it to postfix
"(" ---> Push it on the stack
")" ---> Pop and add to postfix all operators till 1st left parenthesis
Operator ---> Pop and add to postfix those operators that have preceded
greater than or equal to the precedence of scanned operator.
Push the scanned symbol operator on the stack
Dans Préfixe, les opérateurs d'expression viennent en premier, puis les opérandes: + ab [oprator ab]
Infix: (a–b)/c*(d + e – f / g)
Étape 1: (a - b) = (- ab)
['(' a la priorité la plus élevée]
étape 2: (d + e - f / g) = (d + e - / fg)
['/' a la priorité la plus haute]
= (+ de - / fg )
['+','-' has same priority but left to right associativity]
= (- + de / fg)
Étape 3: (-ab )/ c * (- + de / fg)
= / - abc * (- + de / fg)
= * / - abc - + de / fg
Préfixe: * / - abc - + de / fg
https://en.wikipedia.org/wiki/Shunting-yard_algorithm
L’algorithme de la gare de triage peut également être appliqué pour produire le préfixe notation (aussi appelée notation polonaise). Faire cela se ferait simplement commencez à la fin d'une chaîne de jetons à analyser et travaillez à l'envers, inverser la file d'attente de sortie (la pile en sortie étant donc une pile de sortie) et inverser le comportement entre parenthèses gauche et droite (Rappelez-vous que le comportement de parenthèse maintenant gauche doit apparaître jusqu'à ce que il trouve une parenthèse maintenant droite).
from collections import deque
def convertToPN(expression):
precedence = {}
precedence["*"] = precedence["/"] = 3
precedence["+"] = precedence["-"] = 2
precedence[")"] = 1
stack = []
result = deque([])
for token in expression[::-1]:
if token == ')':
stack.append(token)
Elif token == '(':
while stack:
t = stack.pop()
if t == ")": break
result.appendleft(t)
Elif token not in precedence:
result.appendleft(token)
else:
# XXX: associativity should be considered here
# https://en.wikipedia.org/wiki/Operator_associativity
while stack and precedence[stack[-1]] > precedence[token]:
result.appendleft(stack.pop())
stack.append(token)
while stack:
result.appendleft(stack.pop())
return list(result)
expression = "(a - b) / c * (d + e - f / g)".replace(" ", "")
convertToPN(expression)
traverser:
step 1 : token ) ; stack:[ ) ]
result:[ ]
step 2 : token g ; stack:[ ) ]
result:[ g ]
step 3 : token / ; stack:[ ) / ]
result:[ g ]
step 4 : token f ; stack:[ ) / ]
result:[ f g ]
step 5 : token - ; stack:[ ) - ]
result:[ / f g ]
step 6 : token e ; stack:[ ) - ]
result:[ e / f g ]
step 7 : token + ; stack:[ ) - + ]
result:[ e / f g ]
step 8 : token d ; stack:[ ) - + ]
result:[ d e / f g ]
step 9 : token ( ; stack:[ ]
result:[ - + d e / f g ]
step 10 : token * ; stack:[ * ]
result:[ - + d e / f g ]
step 11 : token c ; stack:[ * ]
result:[ c - + d e / f g ]
step 12 : token / ; stack:[ * / ]
result:[ c - + d e / f g ]
step 13 : token ) ; stack:[ * / ) ]
result:[ c - + d e / f g ]
step 14 : token b ; stack:[ * / ) ]
result:[ b c - + d e / f g ]
step 15 : token - ; stack:[ * / ) - ]
result:[ b c - + d e / f g ]
step 16 : token a ; stack:[ * / ) - ]
result:[ a b c - + d e / f g ]
step 17 : token ( ; stack:[ * / ]
result:[ - a b c - + d e / f g ]
# the final while
step 18 : token ( ; stack:[ ]
result:[ * / - a b c - + d e / f g ]
voici une implémentation Java pour convertir l'infixe en préfixe et évaluer l'expression du préfixe (basé sur l'algorithme de rajdip)
import Java.util.*;
public class Expression {
private static int isp(char token){
switch (token){
case '*':
case '/':
return 2;
case '+':
case '-':
return 1;
default:
return -1;
}
}
private static double calculate(double oprnd1,double oprnd2,char oprt){
switch (oprt){
case '+':
return oprnd1+oprnd2;
case '*':
return oprnd1*oprnd2;
case '/':
return oprnd1/oprnd2;
case '-':
return oprnd1-oprnd2;
default:
return 0;
}
}
public static String infix2prefix(String infix) {
Stack<String> OperandStack = new Stack<>();
Stack<Character> OperatorStack = new Stack<>();
for(char token:infix.toCharArray()){
if ('a' <= token && token <= 'z')
OperandStack.Push(String.valueOf(token));
else if (token == '(' || OperatorStack.isEmpty() || isp(token) > isp(OperatorStack.peek()))
OperatorStack.Push(token);
else if(token == ')'){
while (OperatorStack.peek() != '(') {
Character operator = OperatorStack.pop();
String RightOperand = OperandStack.pop();
String LeftOperand = OperandStack.pop();
String operand = operator + LeftOperand + RightOperand;
OperandStack.Push(operand);
}
OperatorStack.pop();
}
else if(isp(token) <= isp(OperatorStack.peek())){
while (!OperatorStack.isEmpty() && isp(token)<= isp(OperatorStack.peek())) {
Character operator = OperatorStack.pop();
String RightOperand = OperandStack.pop();
String LeftOperand = OperandStack.pop();
String operand = operator + LeftOperand + RightOperand;
OperandStack.Push(operand);
}
OperatorStack.Push(token);
}
}
while (!OperatorStack.isEmpty()){
Character operator = OperatorStack.pop();
String RightOperand = OperandStack.pop();
String LeftOperand = OperandStack.pop();
String operand = operator + LeftOperand + RightOperand;
OperandStack.Push(operand);
}
return OperandStack.pop();
}
public static double evaluatePrefix(String prefix, Map values){
Stack<Double> stack = new Stack<>();
prefix = new StringBuffer(prefix).reverse().toString();
for (char token:prefix.toCharArray()){
if ('a'<=token && token <= 'z')
stack.Push((double) values.get(token));
else {
double oprnd1 = stack.pop();
double oprnd2 = stack.pop();
stack.Push(calculate(oprnd1,oprnd2,token));
}
}
return stack.pop();
}
public static void main(String[] args) {
Map dictionary = new HashMap<>();
dictionary.put('a',2.);
dictionary.put('b',3.);
dictionary.put('c',2.);
dictionary.put('d',5.);
dictionary.put('e',16.);
dictionary.put('f',4.);
dictionary.put('g',7.);
String s = "((a+b)/(c-d)+e)*f-g";
System.out.println(evaluatePrefix(infix2prefix(s),dictionary));
}
}