Анализатор с поддержкой переменных - C#

Узнай цену своей работы

Формулировка задачи:

Доброго времени суток! Подскажите как в анализатор арифметических выражений можно подставить вместо буквы значение из массива. Анализатор считает математические выражения (н-р: 10-5/2). Добавил в него возможность распознавания кроме цифр и знаков арифм. операций букв, которым присваивается тип "VARIABLE", но вот как в процессе вычисления вместо них подтянуть их значение из массива хранящего эти значения не знаю. Это нужно для того, что бы например если на вход подаётся функция x^2+2*x+1, программа рассчитала её значения, при х равном определённым значениям, которые будут хранится в массиве. Распознавание переменной прописано в функции get_token, её замена на конкретное значение в account7 (ref double rezult):
    class Program
    {
        
        class kalculiator
        {
        public enum typesT {UNDEFTOK, OPERATOR, NUMBER, VARIABLE};
        
        char[] operators_deistviy = new char[9] { '+', '-', '*', '/', '%', '^', '=', '(', ')' };
 
        string exp_ptr; //содержет вырожение
        int iter=0;
        string token; //содержет текущ лексему
        typesT tok_type; //содержет тип лексемы

        public kalculiator ()
        {
        exp_ptr = "";
        
        }
        public double eval_exp (string exp)
        {
        double rezult=0;
        exp_ptr = exp;
        get_token();
 
        if (String.IsNullOrEmpty(exp_ptr)) return 0.0;
                
        add_sub2 (ref rezult);
        if (iter != exp_ptr.Length) Console.WriteLine("Ошибка! Не достигнут конец строки.");
        return rezult;
        }

        public void add_sub2 (ref double rezult)
        {
        double temp=0;
        string op;
        mul_div_pers3(ref rezult);
        while ((op = token) == "+" || op == "-") //Исправить, после выяснения как замен указ на тек лексему
           {
            get_token();
            mul_div_pers3(ref temp); //Исправить, после выяснения как замен указ на тек лексему
                    switch (op)
              {
                 case "-":
                 rezult = rezult - temp;
                 break;
                 case "+":
                 rezult = rezult + temp;
                 break;
              }
            }
         }
            public void mul_div_pers3 (ref double rezult)
            {
                double temp=0;
                string op;
                stepen4 (ref rezult);
                while ((op = token) == "*" || op == "/" || op == "%") //Исправить, после выяснения как замен указ на тек лексему
                {
                    get_token();
                    stepen4(ref temp);
                    switch (op)
                    {
                        case "*":
                            rezult = rezult * temp;
                            break;
                        case "/":
                          if (temp==0.0) Console.WriteLine("Ошибка! Деление на 0.");
                            else rezult = rezult / temp;
                            break;
                        case "%":
                            rezult = (int)rezult % (int)temp;
                            break;
                    }
                }
 
            }
            public void stepen4 (ref double rezult)
            {
                double temp=0, ex;
                unarn_oper5(ref rezult);
                if (token == "^") //Исправить, после выяснения как замен указ на тек лексему
                {
                    get_token();
                    stepen4(ref temp);
                    ex = rezult;
                    if (temp == 0.0)
                    {
                        rezult = 1.0;
                        return;
                    }
                    for (int t = (int)temp - 1; t > 0; --t) rezult = rezult * (double)ex;
                }
            }
            public void unarn_oper5 (ref double rezult)
            {
                string op="";
             //   skobky6 (ref rezult);
 
                //op = (char)0;
                if ((tok_type == typesT.OPERATOR) && token == "+" || token == "-") //Исправить, после выяснения как замен указ на тек лексему
                {
                    op = token; //Исправить, после выяснения как замен указ на тек лексему
                    get_token();
                }
                skobky6(ref rezult);
                if (op == "-") rezult = -rezult;
            }
            public void skobky6 (ref double rezult)
            {
                if ((token == "(")) //Исправить, после выяснения как замен указ на тек лексему
                {
                    get_token();
                    add_sub2(ref rezult);
                    if (token != ")") Console.WriteLine("Ошибка! Нет закрывающейсяскобки"); //Исправить, после выяснения как замен указ на тек лексему
                    get_token();
                }
                else account7(ref rezult);
            }
 
            public void account7(ref double rezult)
            {
                switch (tok_type)
                {
                    case typesT.NUMBER:
                        rezult = Convert.ToDouble(token); //преобразование строки в тип double
                        get_token();
                       return;
                    case typesT.VARIABLE:
                       
                    //rezult = take_variable(); 
                    get_token();
                    return;
                    default: Console.WriteLine("Ошибка чтения числа/переменной"); return;
 
                }
            }
            public bool isdelim(char c)
            {
                if (c=='+' || c=='-' || c=='*'|| c=='/'|| c=='^' || c=='='|| c=='('|| c==')' || c=='\r') //сравнение символа с 1-м операндом и...
                return true;
                return false;
            }
            public void get_token()
            {
                char [] temp=new char [10]; //??? Нужен аналог указателя!!!
                
                token = "";
                tok_type = typesT.UNDEFTOK; //обнуление типа для анализа следующей лексемы
                
                if (iter==exp_ptr.Length) return;

                if (exp_ptr.IndexOfAny(operators_deistviy, iter, 1) > -1) //
                { //ищет нужный оператор в массиве
                    tok_type = typesT.OPERATOR;
                    token=token+exp_ptr[iter]; iter++;
                }
                
                else if ((int)exp_ptr[iter]>=97 && (int)exp_ptr[iter]<=122)
                { //проверка на принадлежность к букве алфавита
                    while (!isdelim(exp_ptr[iter])) //проверка на разделитель
                    { token = token + exp_ptr[iter]; iter++;}
                tok_type= typesT.VARIABLE; }
                
                else if ((int)exp_ptr[iter] >= 48 && (int)exp_ptr[iter] <= 57)
                { //проверяет на принадлежность к числу
                    while (iter < exp_ptr.Length && !isdelim(exp_ptr[iter]))
                    { token = token + exp_ptr[iter];
                     iter++;}
                    tok_type = typesT.NUMBER;
                }
               
            }
          
        };

Решение задачи: «Анализатор с поддержкой переменных»

textual
Листинг программы
            Parser ob = new Parser();
 
            var array = new int[] { 1, 2, 3, 4 };
            string expr = "x^2+2*x+1";
 
            foreach (var p in array)
            {
                ob.eval_exp(string.Format("x={0}", p));
                Console.WriteLine("{0} for {1} = {2}", expr, p, ob.eval_exp(expr));
            }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 4.273 из 5
Похожие ответы