Last active
February 15, 2022 10:39
-
-
Save octopitus/974d0dc8c6761df741a9 to your computer and use it in GitHub Desktop.
Simple Infix to Postfix conversion in Golang using stack.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"strings" | |
) | |
func IsOperator(c uint8) bool { | |
return strings.ContainsAny(string(c), "+ & - & * & /") | |
} | |
func IsOperand(c uint8) bool { | |
return c >= '0' && c <= '9' | |
} | |
func GetOperatorWeight(op string) int { | |
switch op { | |
case "+", "-": | |
return 1 | |
case "*", "/": | |
return 2 | |
} | |
return -1 | |
} | |
func HasHigherPrecedence(op1 string, op2 string) bool { | |
op1Weight := GetOperatorWeight(op1) | |
op2Weight := GetOperatorWeight(op2) | |
return op1Weight >= op2Weight | |
} | |
func ToPostfix(s string) string { | |
var stack Stack | |
postfix := "" | |
length := len(s) | |
for i := 0; i < length; i++ { | |
char := string(s[i]) | |
// Skip whitespaces | |
if char == " " { | |
continue | |
} | |
if char == "(" { | |
stack.Push(char) | |
} else if char == ")" { | |
for !stack.Empty() { | |
str, _ := stack.Top().(string) | |
if str == "(" { | |
break | |
} | |
postfix += " " + str | |
stack.Pop() | |
} | |
stack.Pop() | |
} else if !IsOperator(s[i]) { | |
// If character is not an operator | |
// Keep in mind it's just an operand | |
j := i | |
number := "" | |
for ; j < length && IsOperand(s[j]); j++ { | |
number = number + string(s[j]) | |
} | |
postfix += " " + number | |
i = j - 1 | |
} else { | |
// If character is operator, pop two elements from stack, | |
// perform operation and push the result back. | |
for !stack.Empty() { | |
top, _ := stack.Top().(string) | |
if top == "(" || !HasHigherPrecedence(top, char) { | |
break | |
} | |
postfix += " " + top | |
stack.Pop() | |
} | |
stack.Push(char) | |
} | |
} | |
for !stack.Empty() { | |
str, _ := stack.Pop().(string) | |
postfix += " " + str | |
} | |
return strings.TrimSpace(postfix) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"fmt" | |
"os" | |
"strings" | |
) | |
func ReadFromInput() (string, error) { | |
reader := bufio.NewReader(os.Stdin) | |
s, err := reader.ReadString('\n') | |
return strings.TrimSpace(s), err | |
} | |
func main() { | |
fmt.Print("Enter infix expression: ") | |
infixString, err := ReadFromInput() | |
if err != nil { | |
fmt.Println("Error when scanning input:", err.Error()) | |
return | |
} | |
fmt.Println("Ya you postfix notation:", ToPostfix(infixString)) | |
return | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
type Stack struct { | |
top *Element | |
size int | |
} | |
type Element struct { | |
value interface{} | |
next *Element | |
} | |
func (s *Stack) Empty() bool { | |
return s.size == 0 | |
} | |
func (s *Stack) Top() interface{} { | |
return s.top.value | |
} | |
func (s *Stack) Push(value interface{}) { | |
s.top = &Element{value, s.top} | |
s.size++ | |
} | |
func (s *Stack) Pop() (value interface{}) { | |
if s.size > 0 { | |
value, s.top = s.top.value, s.top.next | |
s.size-- | |
return | |
} | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment