Извлечение переменных из строкового математического выражения - PullRequest
2 голосов
/ 24 апреля 2011

Я хочу извлечь переменные из математического выражения, используя c #.Я написал этот код, и он работает правильно:

List<string> Variables = new List<string>();
string temp = string.Empty;
Console.WriteLine("Please enter ur expression");
string Expression = Console.ReadLine().Trim();
int Index;
for (Index = 0; Index <= Expression.Length - 1; Index++)
{
    if (char.IsLetter(Expression[Index]))
    {
        temp = temp + Expression[Index];
    }
    else
    {
        if (temp.Length > 0)
        {
            Variables.Add(temp);
            temp = string.Empty;
        }
    }
}
if (temp.Length > 0)
{
    Variables.Add(temp);
}
foreach (string item in Variables)
{
    Console.WriteLine(item);
}
Console.ReadKey();

Мне нужно определить SIN и COS из выражения, поэтому я буду удалять SIN и COS из переменных.

  1. Isэто хороший способ?
  2. Возможно ли это сделать с помощью регулярных выражений или более хорошими способами?
  3. Нужен ли этот код для рефакторинга?

После извлечения я хочу заменить переменныесо значениями из ввода, и я вычислю результат выражения.

Ответы [ 3 ]

3 голосов
/ 24 апреля 2011

Попробуйте набросать автомат, который обнаруживает выражения. После этого самым простым способом реализации автоматов был бы switch..case с вложенным if..else. Я думаю, что это было бы намного проще, чем анализировать строку, как вы сейчас.

Edit -

Это очень простой пример, только для демонстрации. предположим, что я хочу обнаружить выражения в виде var1 + var2, автоматы будут выглядеть так: automata Изображение

Реализация выглядит следующим образом:

done = false;
state = start;
while(!done)
{
    switch(state)
    {
    case start:
        if(expression[i] > 'a' && expression[i] < 'z')
            state = start;
        else if(expression[i] == '+')
        {
            // seen first operand and waitng for second
            // so we switch state
            state = add;
        }
        break;
    case add:
        if(expression[i] > 'a' && expression[i] < 'z')
            state = add;
        else
            done = true;
        break;
    }
}

Как я уже сказал, это очень просто, ваши автоматы будут более сложными с большим количеством состояний и переходов. Я также не включил здесь действия, но вы можете сделать фактическое добавление после того, как прочитан второй операнд, который после done = true;

1 голос
/ 24 апреля 2011

Если вы хотите разобраться в эксперименте самостоятельно, ваши пути кажутся хорошими, но он не оценивает его, в этом случае я предпочитаю использовать предыдущие записанные парсеры, такие как NCalc, вместо того, чтобы создавать Wheal, но если это домашнее задание, и вы просто хотите найти переменные, ваш путь может быть оптимизирован, например, с помощью temp += Expression[Index];, также может быть лучше использовать Experssion.Split(... в этом случае. и если вы хотите разобрать его самостоятельно, вы можете использовать алгоритм закрытия двора.

1 голос
/ 24 апреля 2011

Мне нравится использовать алгоритм Shunting-yard: http://en.wikipedia.org/wiki/Shunting-yard_algorithm Это облегчает eval.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...