-
-
Save mvasilkov/1643235 to your computer and use it in GitHub Desktop.
infix2postfix by https://plus.google.com/u/0/111869347391871267742/posts/NFSgE4bmStw
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
#include <stdio.h> | |
#include <stdlib.h> | |
#include <time.h> | |
#define OPEN_BRACKET_STATE 1 | |
#define CLOSE_BRACKET_STATE 2 | |
#define NUMBER_STATE 3 | |
#define OPERATOR_STATE 4 | |
char OPERATORS[] = {'/', '*', '-', '+'}; | |
const char OPEN_BRACKET = '('; | |
const char CLOSE_BRACKET = ')'; | |
const char SPACE = ' '; | |
void write_symbol(char ch) { | |
printf("%c", ch); | |
} | |
void write_int(int ch) { | |
printf("%i", ch); | |
} | |
int randint(int from, int to) { | |
return from + rand() % to; | |
} | |
int rand_choice_int(int *array, int array_length) { | |
return array[randint(0, array_length)]; | |
} | |
char rand_choice_char(char *array, int array_length) { | |
return array[randint(0, array_length)]; | |
} | |
char get_operator(void) { | |
return rand_choice_char(OPERATORS, 4); | |
} | |
char get_number(void) { | |
return randint(0, 5000); | |
} | |
void generate_infix(long max_symbol_count) { | |
int open_bracket_number_array[] = {OPEN_BRACKET_STATE, NUMBER_STATE}; | |
int state = rand_choice_int(open_bracket_number_array, 2); | |
long bracket_num = 0; | |
long i; | |
for (i = 0; i <= max_symbol_count; i++) { | |
switch (state) { | |
case OPEN_BRACKET_STATE: | |
{ | |
state = NUMBER_STATE; | |
bracket_num++; | |
write_symbol(OPEN_BRACKET); | |
break; | |
} | |
case CLOSE_BRACKET_STATE: | |
{ | |
bracket_num--; | |
state = OPERATOR_STATE; | |
write_symbol(CLOSE_BRACKET); | |
break; | |
} | |
case NUMBER_STATE: | |
{ | |
if (bracket_num) { | |
if (randint(0, 1) == 1) { | |
state = OPERATOR_STATE; | |
} else { | |
state = CLOSE_BRACKET_STATE; | |
} | |
} | |
else { | |
state = OPERATOR_STATE; | |
} | |
write_int(get_number()); | |
break; | |
} | |
case OPERATOR_STATE: | |
{ | |
state = rand_choice_int(open_bracket_number_array, 2); | |
write_symbol(SPACE); | |
write_symbol(get_operator()); | |
write_symbol(SPACE); | |
break; | |
} | |
} | |
} | |
if (state == OPERATOR_STATE) | |
{ | |
write_symbol(SPACE); | |
write_symbol(get_operator()); | |
write_symbol(SPACE); | |
state = NUMBER_STATE; | |
} | |
if (state == OPEN_BRACKET_STATE) { | |
state = NUMBER_STATE; | |
} | |
if (state == NUMBER_STATE) { | |
write_int(get_number()); | |
} | |
if (bracket_num > 0) { | |
for (i = 0; i < bracket_num; i++) { | |
write_symbol(CLOSE_BRACKET); | |
} | |
} | |
} | |
int main(int argc, const char *argv[]) | |
{ | |
unsigned long max_symbol_count; | |
srand(time(NULL)); | |
if (argc > 1) | |
{ | |
max_symbol_count = strtol(argv[1], NULL, 10); | |
} else { | |
max_symbol_count = 1024; | |
} | |
generate_infix(max_symbol_count); | |
return 0; | |
} |
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
# -*- coding: utf-8 -*- | |
import sys | |
import random | |
OPERATORS = '*/-+' | |
OPEN_BRACKET = 1 | |
CLOSE_BRACKET = 2 | |
NUMBER = 3 | |
OPERATOR = 4 | |
def get_operator(): | |
rnd = random.random() | |
rate = 0.0 | |
rate += 0.10 | |
if rnd <= rate: | |
return random.choice("/*") | |
return random.choice("-+") | |
def get_number(): | |
return random.randint(1, 1000) | |
def generate_infix(max_symbol=1024): | |
state = random.choice([OPEN_BRACKET, NUMBER]) | |
bracket_num = 0 | |
for i in xrange(max_symbol): | |
if state == OPEN_BRACKET: | |
state = NUMBER | |
bracket_num += 1 | |
yield "(" | |
elif state == CLOSE_BRACKET: | |
bracket_num -= 1 | |
state = OPERATOR | |
yield ")" | |
elif state == NUMBER: | |
next_states = [OPERATOR] | |
if bracket_num: | |
next_states.append(CLOSE_BRACKET) | |
state = random.choice(next_states) | |
yield get_number() | |
elif state == OPERATOR: | |
state = random.choice([NUMBER, OPEN_BRACKET]) | |
yield " " | |
yield get_operator() | |
yield " " | |
if state == OPERATOR: | |
yield get_operator() | |
state = NUMBER | |
if state == OPEN_BRACKET: | |
state = NUMBER | |
if state == NUMBER: | |
yield get_number() | |
if bracket_num > 0: | |
for i in xrange(bracket_num): | |
yield ")" | |
def test(): | |
for i in xrange(1024): | |
for r in xrange(100): | |
try: | |
result = " ".join(map(str, generate_infix(i))) | |
result, ' = ', eval(result) | |
print "OK" | |
except ZeroDivisionError: | |
print "ZeroDivisionError" | |
def main(): | |
try: | |
length = int(sys.argv[1]) | |
except: | |
length = 1024 | |
#f = open("test.txt", "wb") | |
f = sys.stdout | |
for symbol in generate_infix(length): | |
f.write(str(symbol)) | |
if __name__ == '__main__': | |
#test() | |
main() |
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
#include <stdio.h> | |
#include <stdlib.h> | |
#define size_array(array) (sizeof array)/(sizeof array[0]) | |
char OPERATION[] = {'*', '/', '-', '+'}; | |
char NUMBER[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; | |
char OPEN_BRACKET[] = {'('}; | |
char CLOSE_BRACKET[] = {')'}; | |
int priority_char(char ch) | |
{ | |
switch (ch){ | |
case '(': | |
return 0; | |
case ')': | |
return 0; | |
case 'e': | |
return 0; | |
case '+': | |
return 1; | |
case '-': | |
return 1; | |
case '*': | |
return 2; | |
case '/': | |
return 2; | |
} | |
} | |
int char_in_array(char ch, char *array, int array_len) { | |
int i; | |
for (i = 0; i < array_len; i++) { | |
if (ch == array[i]) { | |
return 1; | |
} | |
} | |
return 0; | |
} | |
void write_result(char ch) { | |
printf("%c", ch); | |
} | |
void infix2postfix(FILE * file) { | |
int i; | |
int c; | |
char stack[255]; | |
char ch; | |
char number_str[255]; | |
int number_str_len = 0; | |
i = 0; | |
stack[0] = 'e'; | |
while ((ch = (char)fgetc(file)) != -1) { | |
if (!char_in_array(ch, NUMBER, size_array(NUMBER)) && number_str_len) { | |
printf("%s ", number_str); | |
number_str_len = 0; | |
} | |
if (char_in_array(ch, OPERATION, size_array(OPERATION))) | |
{ | |
while (1) | |
{ | |
if (priority_char(ch) > priority_char(stack[i])) | |
{ | |
i++; | |
stack[i] = ch; | |
break; | |
} | |
else { | |
write_result(stack[i]); | |
i--; | |
} | |
} | |
continue; | |
} | |
if (char_in_array(ch, NUMBER, size_array(NUMBER))) | |
{ | |
number_str[number_str_len] = ch; | |
number_str[number_str_len + 1] = '\0'; | |
number_str_len++; | |
continue; | |
} | |
if (char_in_array(ch, OPEN_BRACKET, size_array(OPEN_BRACKET))) | |
{ | |
i++; | |
stack[i] = ch; | |
continue; | |
} | |
if (char_in_array(ch, CLOSE_BRACKET, size_array(CLOSE_BRACKET))) | |
{ | |
while (1) | |
{ | |
if (char_in_array(stack[i], OPEN_BRACKET, size_array(OPEN_BRACKET))) | |
{ | |
i--; | |
break; | |
} | |
else | |
{ | |
write_result(stack[i]); | |
i--; | |
} | |
} | |
continue; | |
} | |
} | |
int j; | |
for (j = 1; i < j; j++) { | |
write_result(stack[i]); | |
} | |
} | |
int main(int argc, const char *argv[]) | |
{ | |
FILE * file; | |
if (argc > 1) | |
{ | |
file = fopen(argv[1], "r"); | |
} else { | |
file = stdin; | |
} | |
infix2postfix(file); | |
printf("\n"); | |
return 0; | |
} |
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
# -*- coding: utf-8 -*- | |
import sys | |
import string | |
OPERATION = ['*', '/', '-', '+'] | |
NUM = string.digits | |
ALPHA = string.ascii_lowercase | |
ALPHANUM = NUM + ALPHA | |
EMPTY = string.whitespace | |
OPEN_BRACKET = ['('] | |
CLOSE_BRACKET = [')'] | |
def priority_char(ch): | |
''' | |
Функция приоритета | |
''' | |
if ch in ['(', ')', 'e']: | |
return 0 | |
if ch in ['+', '-']: | |
return 1 | |
if ch in ['*', '/']: | |
return 2 | |
def infix2postfix(str_iter): | |
''' | |
python style | |
''' | |
stack = [] | |
number_str = '' | |
stack.append('e') | |
for ch in str_iter: | |
if ch not in NUM and number_str: | |
yield number_str | |
number_str = '' | |
if ch in OPERATION: | |
while True: | |
if priority_char(ch) > priority_char(stack[-1]): | |
stack.append(ch) | |
break | |
else: | |
yield stack.pop() | |
elif ch in ALPHANUM: | |
number_str += ch | |
elif ch in OPEN_BRACKET: | |
stack.append(ch) | |
elif ch in CLOSE_BRACKET: | |
while True: | |
ch = stack.pop() | |
if ch in OPEN_BRACKET: | |
break | |
else: | |
yield ch | |
if number_str: | |
yield number_str | |
for s in reversed(stack[1:]): | |
yield s | |
FUNC_MAP = { | |
'+': lambda x, y: x + y, | |
'-': lambda x, y: x - y, | |
'/': lambda x, y: x / y, | |
'*': lambda x, y: x * y, | |
} | |
def postfix_calculate(iterator, stack=None): | |
if not stack: | |
stack = [] | |
for char in iterator: | |
try: | |
stack.append(float(char)) | |
except ValueError: | |
func = FUNC_MAP[char] | |
y = stack.pop() | |
x = stack.pop() | |
stack.append(func(x, y)) | |
return stack[0] | |
def test(): | |
result = list(infix2postfix("(1+2)/(3*2)-5")) | |
assert " ".join(result) == '1 2 + 3 2 * / 5 -', result | |
assert postfix_calculate(result) == -4.5 | |
result = list(infix2postfix("(1+12)/(30*232)-50")) | |
assert " ".join(result) == '1 12 + 30 232 * / 50 -', result | |
assert -49.9 >= postfix_calculate(result) >= -50.0 | |
result = list(infix2postfix("1 + 2 * (3 - 4) / 5")) | |
assert " ".join(result) == '1 2 3 4 - * 5 / +', result | |
assert postfix_calculate(result) == (1. + 2. * (3. - 4.) / 5.) | |
result = list(infix2postfix("(1) + (1)")) | |
assert " ".join(result) == '1 1 +', result | |
assert postfix_calculate(result) == (1 + 1) | |
def file_reader(file_obj, buf_size=1024): | |
''' | |
Посимвольное чтение из файла | |
''' | |
str_buf = file_obj.read(buf_size) | |
while str_buf: | |
for ch in str_buf: | |
yield ch | |
str_buf = file_obj.read(buf_size) | |
def main(): | |
try: | |
file_obj = open(sys.argv[1]) | |
except IndexError: | |
file_obj = sys.stdin | |
print postfix_calculate(infix2postfix(file_reader(file_obj))) | |
def main_final(): | |
try: | |
file_obj = open(sys.argv[1]) | |
except IndexError: | |
file_obj = sys.stdin | |
for symbol in infix2postfix(file_reader(file_obj)): | |
sys.stdout.write(str(symbol)) | |
if __name__ == '__main__': | |
if "--calc" in sys.argv: | |
sys.argv.remove("--calc") | |
main() | |
else: | |
main_final() | |
#test() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment