Важная информация
Показано с 1 по 2 из 2

Тема: Реализация ввода функции через TextBox

  1. #1 Реализация ввода функции через TextBox 
    Новичок
    Регистрация
    28.04.2017
    Сообщений
    1
    Сказал(а) спасибо
    0
    Поблагодарили 0 раз(а) в 0 сообщениях
    Здравствуйте, я новичок в си шарпе и у меня возникла следующая проблема. Нужно реализовать ввод функции через текстбокс.
    Начала писать код,
    C# Code:
    1.  
    2. private void Form1_Load(object sender, EventArgs e)
    3.         {
    4.             string input = (textBox1.Text); // строка которую нужно разобрать
    5.             Function f = [Ссылки могут видеть только зарегистрированные пользователи. ] Function(input); // создаем функцию
    6.             double result;
    7.             return result = f.calculate(x);
    8.         }

    дальше вроде нашла строки для разбора функции то есть типо парсера что то
    C# Code:
    1.  
    2. public class Parser
    3.   {
    4.     public const char START_ARG = '(';
    5.     public const char END_ARG   = ')';
    6.     public const char END_LINE  = '\n';
    7.  
    8.     class Cell
    9.     {
    10.       internal Cell(double value, char action)
    11.       {
    12.         Value = value;
    13.         Action = action;
    14.       }
    15.  
    16.       internal double Value  { get; set; }
    17.       internal char   Action { get; set; }
    18.     }
    19.  
    20.     public static double process(string data)
    21.     {
    22.       // Get rid of spaces and check parenthesis
    23.       string expression = preprocess(data);
    24.       int from = 0;
    25.  
    26.       return loadAndCalculate(data, ref from, END_LINE);
    27.     }
    28.  
    29.     static string preprocess(string data)
    30.     {
    31.       if (string.IsNullOrEmpty(data))
    32.       {
    33.         throw [Ссылки могут видеть только зарегистрированные пользователи. ] ArgumentException("Loaded empty data");
    34.       }
    35.  
    36.       int parentheses = 0;
    37.       StringBuilder result = [Ссылки могут видеть только зарегистрированные пользователи. ] StringBuilder(data.Length);
    38.  
    39.       for (int i = 0; i < data.Length; i++)
    40.       {
    41.         char ch = data[i];
    42.         switch (ch)
    43.         {
    44.           case ' ':
    45.           case '\t':
    46.           case '\n': continue;
    47.           case END_ARG:   parentheses--;
    48.             break;
    49.           case START_ARG: parentheses++;
    50.             break;
    51.         }
    52.         result.Append(ch);
    53.       }
    54.  
    55.       if (parentheses != 0)
    56.       {
    57.         throw [Ссылки могут видеть только зарегистрированные пользователи. ] ArgumentException("Uneven parenthesis");
    58.       }
    59.  
    60.       return result.ToString();
    61.     }
    62.  
    63.     public static double loadAndCalculate(string data, ref int from, char to = END_LINE)
    64.     {
    65.       if (from >= data.Length || data[from] == to)
    66.       {
    67.         throw [Ссылки могут видеть только зарегистрированные пользователи. ] ArgumentException("Loaded invalid data: " + data);
    68.       }
    69.  
    70.       List<Cell> listToMerge = [Ссылки могут видеть только зарегистрированные пользователи. ] List<Cell>(16);
    71.       StringBuilder item = [Ссылки могут видеть только зарегистрированные пользователи. ] StringBuilder();
    72.  
    73.       do
    74.       { // Main processing cycle of the first part.
    75.         char ch = data[from++];
    76.         if (stillCollecting(item.ToString(), ch, to))
    77.         { // The char still belongs to the previous operand.
    78.           item.Append(ch);
    79.           if (from < data.Length && data[from] != to)
    80.           {
    81.             continue;
    82.           }
    83.         }
    84.  
    85.         // We are done getting the next token. The getValue() call below may
    86.         // recursively call loadAndCalculate(). This will happen if extracted
    87.         // item is a function or if the next item is starting with a START_ARG '('.
    88.         ParserFunction func = [Ссылки могут видеть только зарегистрированные пользователи. ] ParserFunction(data, ref from, item.ToString(), ch);
    89.         double value = func.getValue(data, ref from);
    90.  
    91.         char action = validAction(ch) ? ch
    92.                                       : updateAction(data, ref from, ch, to);
    93.  
    94.         listToMerge.Add([Ссылки могут видеть только зарегистрированные пользователи. ] Cell(value, action));
    95.         item.Clear();
    96.  
    97.       } while (from < data.Length && data[from] != to);
    98.  
    99.       if (from < data.Length &&
    100.          (data[from] == END_ARG || data[from] == to))
    101.       { // This happens when called recursively: move one char forward.
    102.         from++;
    103.       }
    104.  
    105.       Cell baseCell = listToMerge[0];
    106.       int index = 1;
    107.  
    108.       return merge(baseCell, ref index, listToMerge);
    109.     }
    110.  
    111.     static bool stillCollecting(string item, char ch, char to)
    112.     {
    113.       // Stop collecting if either got END_ARG ')' or to char, e.g. ','.
    114.       char stopCollecting = (to == END_ARG || to == END_LINE) ?
    115.                              END_ARG : to;
    116.       return (item.Length == 0 && (ch == '-' || ch == END_ARG)) ||
    117.             !(validAction(ch) || ch == START_ARG || ch == stopCollecting);
    118.     }
    119.  
    120.     static bool validAction(char ch)
    121.     {
    122.       return ch == '*' || ch == '/' || ch == '+' || ch == '-' || ch == '^';
    123.     }
    124.  
    125.     static char updateAction(string item, ref int from, char ch, char to)
    126.     {
    127.       if (from >= item.Length || item[from] == END_ARG || item[from] == to)
    128.       {
    129.         return END_ARG;
    130.       }
    131.  
    132.       int index = from;
    133.       char res = ch;
    134.       while (!validAction(res) && index < item.Length)
    135.       { // Look for the next character in string until a valid action is found.
    136.         res = item[index++];
    137.       }
    138.  
    139.       from = validAction(res) ? index
    140.                               : index > from ? index - 1
    141.                                              : from;
    142.       return res;
    143.     }
    144.  
    145.     // From outside this function is called with mergeOneOnly = false.
    146.     // It also calls itself recursively with mergeOneOnly = true, meaning
    147.     // that it will return after only one merge.
    148.     static double merge(Cell current, ref int index, List<Cell> listToMerge,
    149.                  bool mergeOneOnly = false)
    150.     {
    151.       while (index < listToMerge.Count)
    152.       {
    153.         Cell next = listToMerge[index++];
    154.  
    155.         while (!canMergeCells(current, next))
    156.         { // If we cannot merge cells yet, go to the next cell and merge
    157.           // next cells first. E.g. if we have 1+2*3, we first merge next
    158.           // cells, i.e. 2*3, getting 6, and then we can merge 1+6.
    159.           merge(next, ref index, listToMerge, true /* mergeOneOnly */);
    160.         }
    161.         mergeCells(current, next);
    162.         if (mergeOneOnly)
    163.         {
    164.           return current.Value;
    165.         }
    166.       }
    167.  
    168.       return current.Value;
    169.     }
    170.  
    171.     static void mergeCells(Cell leftCell, Cell rightCell)
    172.     {
    173.       switch (leftCell.Action)
    174.       {
    175.         case '^': leftCell.Value = Math.Pow(leftCell.Value, rightCell.Value);
    176.           break;
    177.         case '*': leftCell.Value *= rightCell.Value;
    178.           break;
    179.         case '/':
    180.           if (rightCell.Value == 0)
    181.           {
    182.             throw [Ссылки могут видеть только зарегистрированные пользователи. ] ArgumentException("Division by zero");
    183.           }
    184.           leftCell.Value /= rightCell.Value;
    185.           break;
    186.         case '+': leftCell.Value += rightCell.Value;
    187.           break;
    188.         case '-': leftCell.Value -= rightCell.Value;
    189.           break;
    190.       }
    191.       leftCell.Action = rightCell.Action;
    192.     }
    193.  
    194.     static bool canMergeCells(Cell leftCell, Cell rightCell)
    195.     {
    196.       return getPriority(leftCell.Action) >= getPriority(rightCell.Action);
    197.     }
    198.  
    199.     static int getPriority(char action)
    200.     {
    201.       switch (action) {
    202.         case '^': return 4;
    203.         case '*':
    204.         case '/': return 3;
    205.         case '+':
    206.         case '-': return 2;
    207.       }
    208.       return 0;
    209.     }
    210.   }
    211.  
    212.   public class ParserFunction
    213.   {
    214.     public ParserFunction()
    215.     {
    216.       m_impl = this;
    217.     }
    218.  
    219.     // A "virtual" Constructor
    220.     internal ParserFunction(string data, ref int from, string item, char ch)
    221.     {
    222.       if (item.Length == 0 && ch == Parser.START_ARG)
    223.       {
    224.         // There is no function, just an expression in parentheses
    225.         m_impl = s_idFunction;
    226.         return;
    227.       }
    228.  
    229.       if (m_functions.TryGetValue(item, out m_impl))
    230.       {
    231.         // Function exists and is registered (e.g. pi, exp, etc.)
    232.         return;
    233.       }
    234.  
    235.       // Function not found, will try to parse this as a number.
    236.       s_strtodFunction.Item = item;
    237.       m_impl = s_strtodFunction;
    238.     }
    239.  
    240.     public static void addFunction(string name, ParserFunction function)
    241.     {
    242.       m_functions[name] = function;
    243.     }
    244.  
    245.     public double getValue(string data, ref int from)
    246.     {
    247.       return m_impl.evaluate(data, ref from);
    248.     }
    249.  
    250.     protected virtual double evaluate(string data, ref int from)
    251.     {
    252.       // The real implementation will be in the derived classes.
    253.       return 0;
    254.     }
    255.  
    256.     private ParserFunction m_impl;
    257.     private static Dictionary<string, ParserFunction> m_functions = [Ссылки могут видеть только зарегистрированные пользователи. ] Dictionary<string, ParserFunction>();
    258.  
    259.     private static StrtodFunction s_strtodFunction = [Ссылки могут видеть только зарегистрированные пользователи. ] StrtodFunction();
    260.     private static IdentityFunction s_idFunction = [Ссылки могут видеть только зарегистрированные пользователи. ] IdentityFunction();
    261.   }
    262.  
    263.   class StrtodFunction : ParserFunction
    264.   {
    265.     protected override double evaluate(string data, ref int from)
    266.     {
    267.       double num;
    268.       if (!Double.TryParse(Item, out num)) {
    269.         throw [Ссылки могут видеть только зарегистрированные пользователи. ] ArgumentException("Could not parse token [" + Item + "]");
    270.       }
    271.       return num;
    272.     }
    273.     public string Item { private get; set; }
    274.   }
    275.  
    276.   class IdentityFunction : ParserFunction
    277.   {
    278.     protected override double evaluate(string data, ref int from)
    279.     {
    280.       return Parser.loadAndCalculate(data, ref from, Parser.END_ARG);
    281.     }
    282.   }
    283.  
    284.   class PiFunction : ParserFunction
    285.   {
    286.     protected override double evaluate(string data, ref int from)
    287.     {
    288.       return 3.141592653589793;
    289.     }
    290.   }
    291.   class ExpFunction : ParserFunction
    292.   {
    293.     protected override double evaluate(string data, ref int from)
    294.     {
    295.       double arg = Parser.loadAndCalculate(data, ref from, Parser.END_ARG);
    296.       return Math.Exp(arg);
    297.     }
    298.   }
    299.   class PowFunction : ParserFunction
    300.   {
    301.     protected override double evaluate(string data, ref int from)
    302.     {
    303.       double arg1 = Parser.loadAndCalculate(data, ref from, ',');
    304.       double arg2 = Parser.loadAndCalculate(data, ref from, Parser.END_ARG);
    305.  
    306.       return Math.Pow(arg1, arg2);
    307.     }
    308.   }
    309.   class SinFunction : ParserFunction
    310.   {
    311.     protected override double evaluate(string data, ref int from)
    312.     {
    313.       double arg = Parser.loadAndCalculate(data, ref from, Parser.END_ARG);
    314.       return Math.Sin(arg);
    315.     }
    316.   }
    317.   class SqrtFunction : ParserFunction
    318.   {
    319.     protected override double evaluate(string data, ref int from)
    320.     {
    321.       double arg = Parser.loadAndCalculate(data, ref from, Parser.END_ARG);
    322.       return Math.Sqrt(arg);
    323.     }
    324.   }
    325.   class AbsFunction : ParserFunction
    326.   {
    327.     protected override double evaluate(string data, ref int from)
    328.     {
    329.       double arg = Parser.loadAndCalculate(data, ref from, Parser.END_ARG);
    330.       return Math.Abs(arg);
    331.     }
    332.   }

    и еще
    C# Code:
    1.  
    2. class Program
    3.   {
    4.     static void calculate(string expr, double expected)
    5.     {
    6.       double result = Parser.process(expr);
    7.  
    8.       string outcome = result == expected ? "OK" : "NOK " + expected.ToString();
    9.       Console.WriteLine("{0} --> {1} ({2})", expr, result, outcome);
    10.     }
    11.  
    12.     static void Main(string[] args)
    13.     {
    14.       ParserFunction.addFunction("pi",   [Ссылки могут видеть только зарегистрированные пользователи. ] PiFunction());
    15.       ParserFunction.addFunction("exp",  [Ссылки могут видеть только зарегистрированные пользователи. ] ExpFunction());
    16.       ParserFunction.addFunction("pow",  [Ссылки могут видеть только зарегистрированные пользователи. ] PowFunction());
    17.       ParserFunction.addFunction("sin",  [Ссылки могут видеть только зарегистрированные пользователи. ] SinFunction());
    18.       ParserFunction.addFunction("abs",  [Ссылки могут видеть только зарегистрированные пользователи. ] AbsFunction());
    19.       ParserFunction.addFunction("sqrt", [Ссылки могут видеть только зарегистрированные пользователи. ] SqrtFunction());
    20.  
    21.       calculate("(((-5.5)))", (((-5.5))));
    22.       calculate("1-2", 1 - 2);
    23.       calculate("(1-(2))", (1 - (2)));
    24.       calculate("3+2*6-1", 3 + 2 * 6 - 1);
    25.       calculate("3-2*6-1", 3 - 2 * 6 - 1);
    26.       calculate("1-2-3-(4-(5-(6-7)))", 1 - 2 - 3 - (4 - (5 - (6 - 7))));
    27.       calculate("2-3*sin(pi)", 2 - 3 * Math.Sin(Math.PI));
    28.       calculate("1-(exp(10*7-sqrt((1+1)*20*10)))", 1 - (Math.Exp(10 * 7 - Math.Sqrt((1 + 1) * 20 * 10))));
    29.       calculate("3-(5-6)-(2-(3-(1-2)))", 3 - (5 - 6) - (2 - (3 - (1 - 2))));
    30.       calculate("3-(5-6)-(2-(3-(1+2)))+2-(-1+7)*(9-2)/((16-3)-3)+15/2*5",
    31.         3 - (5 - 6) - (2 - (3 - (1 + 2))) + 2 - (-1 + 7) * (9 - 2) / ((16.0 - 3) - 3.0) + 15 / 2.0 * 5);
    32.       calculate("(-1+7)*(9-2)", (-1 + 7) * (9 - 2));
    33.       calculate("((16-3)-3)+15/2*5", ((16 - 3) - 3) + 15 / 2.0 * 5);
    34.       calculate("1+15/2*5", 1 + 15 / 2.0 * 5);
    35.       calculate("3-2/6-1", 3-2/6.0-1);
    36.       calculate("3*50-3*2^4*3", 3 * 50 - 3 * Math.Pow(2, 4) * 3);
    37.       calculate("5-1/2^2-3", 5 - 1 / Math.Pow(2, 2) - 3);
    38.       calculate("(((1/4/2-(8/2/3+5))))", (((1 / 4.0 / 2.0 - (8 / 2.0 / 3.0 + 5)))));
    39.       calculate("pow(2,3)", Math.Pow(2, 3));
    40.       calculate("abs(3*-50-2*3/4)/3*2", Math.Abs(3.0 * -50 - 2 * 3.0 / 4.0) / 3.0 * 2);
    41.  
    42.       Console.ReadKey();
    43.     }
    44.   }

    и никак не могу понять, как переделать это под си шарп и совместить это все
    получается это создание классов, где идет распознавание введенных символов.
    Кто может подсказать как все вместе совместить, что бы работало?
    Буду премного благодарна.
    Ответить с цитированием  
     

  2. #2  
    Разбирающийся
    Регистрация
    18.04.2014
    Адрес
    Ярославль
    Сообщений
    69
    Сказал(а) спасибо
    0
    Поблагодарили 65 раз(а) в 33 сообщениях
    Записей в блоге
    2
    Это небольшой движок для выполнения расчётов с ипользованием функций.

    //Сначала функции надо зарегистировать
    ParserFunction.addFunction("pi", new PiFunction()); //Регистрация возможной функции

    calculate("(((-5.5)))", (((-5.5)))); //выполнение расчётов

    То есть вам что бы воспользоваться данным модулем нужно:
    при старте программы зарегистирировать возможные функции


    C# Code:
    1.       ParserFunction.addFunction("pi",   [Ссылки могут видеть только зарегистрированные пользователи. ] PiFunction());
    2.       ParserFunction.addFunction("exp",  [Ссылки могут видеть только зарегистрированные пользователи. ] ExpFunction());
    3.       ParserFunction.addFunction("pow",  [Ссылки могут видеть только зарегистрированные пользователи. ] PowFunction());
    4.       ParserFunction.addFunction("sin",  [Ссылки могут видеть только зарегистрированные пользователи. ] SinFunction());
    5.       ParserFunction.addFunction("abs",  [Ссылки могут видеть только зарегистрированные пользователи. ] AbsFunction());
    6.       ParserFunction.addFunction("sqrt", [Ссылки могут видеть только зарегистрированные пользователи. ] SqrtFunction());


    Сделать форму ввода функции в ExpressionTextBox с кнопкой CalculateBtn и областью вывода ответа ResultText.
    по нажатю на кнопку CalculateBtn брать значение ExpressionTextBox и предовать в функцию parse.
    Код ПРИМЕРНО такой:


    C# Code:
    1.       double result = Parser.process([текст из текстбокса]);
    2.       ResultText.setText(result.toString());
    Последний раз редактировалось Игорь Черепов; 02.05.2017 в 13:06.
    Ответить с цитированием  
     

  3. 2 пользователя(ей) сказали cпасибо:

    >Quiet Snow< (02.05.2017), Free Admin (03.05.2017)

Информация о теме
Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Ответов: 120
    Последнее сообщение: 23.03.2016, 18:01
  2. Вставка компонента TextBox в Word
    от CottonHill в разделе VBA
    Ответов: 0
    Последнее сообщение: 03.12.2015, 17:12
  3. реализация интерфейса IComparable<>
    от SemenKandiba в разделе .NET
    Ответов: 4
    Последнее сообщение: 26.08.2015, 13:39
  4. Ответов: 1
    Последнее сообщение: 25.09.2014, 23:57
  5. Ответов: 4
    Последнее сообщение: 26.05.2014, 17:52
Ваши права
  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •