2016-02-05 2 views
-5

Я пишу код для решения арифметических выражений, как: 4+3-2*6*(3+4/2)Сравнивая символы

Для этого мне нужно сравнить оператор в строке с старшинством, как:

1. (or) 
2. * or/
3. + or - 

Может кто-нибудь сказать мне, как сравните два символа. Поскольку их значения ASCII не в том порядке, который я хочу!

+0

Почему бы просто не сделать свою собственную функцию сравнения? –

+0

Yupp Я мог бы это сделать, но я искал, есть ли другой эффективный способ сделать это! Как я мог определить свои значения ascii для операторов, я знаю, что это невозможно, но что-то похожее на это. –

+0

Также .. Например. арифметического выражения, которое я дал в que. это простая версия. Более сложное арифметическое выражение может включать в себя другие абстрактные операторы типа «$», «%», «^», «@», «&» и т. Д., Причем их операция определяется двумя целыми числами и приоритетом над другими операторами. Вы не можете просто сделать функцию для этого! Для написания этой функции потребуется 100 строк. (Подумайте о выборе 3 операторов для сравнения с n операторами). –

ответ

2

Используйте таблицу поиска. Если используется ASCII, это всего лишь таблица из 256 элементов. Вы индексируете его символом.

+0

Что вы имеете в виду, говоря: «Индексируйте его с помощью char» .. пожалуйста, продумайте его! –

+0

, если у вас есть символ в переменной 'c', а ваш массив' A', просто выполните 'A [c]', чтобы получить приоритет символа. –

+0

Что делать, если я должен дать двум или более операторам тот же приоритет.В этом случае это не сработает. Прочитайте мой третий комментарий в que.! –

1

Даже в ASCII порядок целых чисел остается неизменным. Вы можете сравнить отдельные цифры. Например:

if ('7' > '2') оценит истинной

2

Для этого мне нужно сравнить операторов в строке с старшинства как:

Вы можете сделать что-то подобное, чтобы получить преимущество для каждого персонажа:

int get_precedence (char c) { 
    switch (c) { 
     case '+': 
     case '-': return 3; 

     case '*': 
     case '/': return 2; 

     case '(': 
     case ')': return 1; 

     default: return -1; 
    } 
} 

Это делает его очень простым в добавлении дополнительных символов по мере необходимости ,

Однако у вас все еще есть некоторые проблемы. Например, как вы скажете унарное отрицание от вычитания? Вам нужно посмотреть на контекст, потому что ответ будет зависеть от того, что было раньше. Работа с инфиксной нотой - hard.

Для этого вам необходимо написать recursive descent parser или использовать shunting yard algorithm. В любом случае, это будет несколько сотен строк hard. Затем вам нужно будет решить, оцениваете ли вы из абстрактного дерева синтаксиса или компилируете в байтовый код.

Я пишу код для решения арифметических выражений как: 4+3-2*6*(3+4/2)

Если вы хотите, чтобы решить, что в легком пути, вы должны найти предварительно существующую библиотеку. TinyExpr - одно из таких решений. Он является открытым исходным кодом и содержится в одном файле исходного кода C. Код для этого будет выглядеть так:

#include "tinyexpr.h" 
double answer = te_interp("4+3-2*6*(3+4/2)", 0); 
+0

Ницца первый раз ответ. ИМО, лучший. – chux