Технический форум
Вернуться   Технический форум > Программирование > Форум программистов > Помощь студентам


Ответ
 
Опции темы Опции просмотра
Старый 28.04.2017, 23:20   #1 (permalink)
Dasha111
Новичок
 
Регистрация: 28.04.2017
Сообщений: 1
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию Ввод функции в Textbox

Здравствуйте, мне необходимо реализовать ввод функции через текстбокс.
Начала писать код:
Код:
 private void Form1_Load(object sender, EventArgs e)
        {
            string input = (textBox1.Text); // строка которую нужно разобрать
            Function f = new Function(input); // создаем функцию
            double result;
            return result = f.calculate(x);
        }
и нашла код для распознавания самой функции
Код:
public class Parser
  {
    public const char START_ARG = '(';
    public const char END_ARG   = ')';
    public const char END_LINE  = '\n';
 
    class Cell
    {
      internal Cell(double value, char action)
      {
        Value = value;
        Action = action;
      }
 
      internal double Value  { get; set; }
      internal char   Action { get; set; }
    }
 
    public static double process(string data)
    {
      // Get rid of spaces and check parenthesis
      string expression = preprocess(data);
      int from = 0;
 
      return loadAndCalculate(data, ref from, END_LINE);
    }
 
    static string preprocess(string data)
    {
      if (string.IsNullOrEmpty(data))
      {
        throw new ArgumentException("Loaded empty data");
      }
 
      int parentheses = 0;
      StringBuilder result = new StringBuilder(data.Length);
 
      for (int i = 0; i < data.Length; i++)
      {
        char ch = data[i];
        switch (ch)
        {
          case ' ':
          case '\t':
          case '\n': continue;
          case END_ARG:   parentheses--;
            break;
          case START_ARG: parentheses++;
            break;
        }
        result.Append(ch);
      }
 
      if (parentheses != 0)
      {
        throw new ArgumentException("Uneven parenthesis");
      }
 
      return result.ToString();
    }
 
    public static double loadAndCalculate(string data, ref int from, char to = END_LINE)
    {
      if (from >= data.Length || data[from] == to)
      {
        throw new ArgumentException("Loaded invalid data: " + data);
      }
 
      List<Cell> listToMerge = new List<Cell>(16);
      StringBuilder item = new StringBuilder();
 
      do
      { // Main processing cycle of the first part.
        char ch = data[from++];
        if (stillCollecting(item.ToString(), ch, to))
        { // The char still belongs to the previous operand.
          item.Append(ch);
          if (from < data.Length && data[from] != to)
          {
            continue;
          }
        }
 
        // We are done getting the next token. The getValue() call below may
        // recursively call loadAndCalculate(). This will happen if extracted
        // item is a function or if the next item is starting with a START_ARG '('.
        ParserFunction func = new ParserFunction(data, ref from, item.ToString(), ch);
        double value = func.getValue(data, ref from);
 
        char action = validAction(ch) ? ch
                                      : updateAction(data, ref from, ch, to);
 
        listToMerge.Add(new Cell(value, action));
        item.Clear();
 
      } while (from < data.Length && data[from] != to);
 
      if (from < data.Length &&
         (data[from] == END_ARG || data[from] == to))
      { // This happens when called recursively: move one char forward.
        from++;
      }
 
      Cell baseCell = listToMerge[0];
      int index = 1;
 
      return merge(baseCell, ref index, listToMerge);
    }
 
    static bool stillCollecting(string item, char ch, char to)
    {
      // Stop collecting if either got END_ARG ')' or to char, e.g. ','.
      char stopCollecting = (to == END_ARG || to == END_LINE) ?
                             END_ARG : to;
      return (item.Length == 0 && (ch == '-' || ch == END_ARG)) ||
            !(validAction(ch) || ch == START_ARG || ch == stopCollecting);
    }
 
    static bool validAction(char ch)
    {
      return ch == '*' || ch == '/' || ch == '+' || ch == '-' || ch == '^';
    }
 
    static char updateAction(string item, ref int from, char ch, char to)
    {
      if (from >= item.Length || item[from] == END_ARG || item[from] == to)
      {
        return END_ARG;
      }
 
      int index = from;
      char res = ch;
      while (!validAction(res) && index < item.Length)
      { // Look for the next character in string until a valid action is found.
        res = item[index++];
      }
 
      from = validAction(res) ? index
                              : index > from ? index - 1
                                             : from;
      return res;
    }
 
    // From outside this function is called with mergeOneOnly = false.
    // It also calls itself recursively with mergeOneOnly = true, meaning
    // that it will return after only one merge.
    static double merge(Cell current, ref int index, List<Cell> listToMerge,
                 bool mergeOneOnly = false)
    {
      while (index < listToMerge.Count)
      {
        Cell next = listToMerge[index++];
 
        while (!canMergeCells(current, next))
        { // If we cannot merge cells yet, go to the next cell and merge
          // next cells first. E.g. if we have 1+2*3, we first merge next
          // cells, i.e. 2*3, getting 6, and then we can merge 1+6.
          merge(next, ref index, listToMerge, true /* mergeOneOnly */);
        }
        mergeCells(current, next);
        if (mergeOneOnly)
        {
          return current.Value;
        }
      }
 
      return current.Value;
    }
 
    static void mergeCells(Cell leftCell, Cell rightCell)
    {
      switch (leftCell.Action)
      {
        case '^': leftCell.Value = Math.Pow(leftCell.Value, rightCell.Value);
          break;
        case '*': leftCell.Value *= rightCell.Value;
          break;
        case '/':
          if (rightCell.Value == 0)
          {
            throw new ArgumentException("Division by zero");
          }
          leftCell.Value /= rightCell.Value;
          break;
        case '+': leftCell.Value += rightCell.Value;
          break;
        case '-': leftCell.Value -= rightCell.Value;
          break;
      }
      leftCell.Action = rightCell.Action;
    }
 
    static bool canMergeCells(Cell leftCell, Cell rightCell)
    {
      return getPriority(leftCell.Action) >= getPriority(rightCell.Action);
    }
 
    static int getPriority(char action)
    {
      switch (action) {
        case '^': return 4;
        case '*':
        case '/': return 3;
        case '+':
        case '-': return 2;
      }
      return 0;
    }
  }
 
  public class ParserFunction
  {
    public ParserFunction()
    {
      m_impl = this;
    }
 
    // A "virtual" Constructor
    internal ParserFunction(string data, ref int from, string item, char ch)
    {
      if (item.Length == 0 && ch == Parser.START_ARG)
      {
        // There is no function, just an expression in parentheses
        m_impl = s_idFunction;
        return;
      }
 
      if (m_functions.TryGetValue(item, out m_impl))
      {
        // Function exists and is registered (e.g. pi, exp, etc.)
        return;
      }
 
      // Function not found, will try to parse this as a number.
      s_strtodFunction.Item = item;
      m_impl = s_strtodFunction;
    }
 
    public static void addFunction(string name, ParserFunction function)
    {
      m_functions[name] = function;
    }
 
    public double getValue(string data, ref int from)
    {
      return m_impl.evaluate(data, ref from);
    }
 
    protected virtual double evaluate(string data, ref int from)
    {
      // The real implementation will be in the derived classes.
      return 0;
    }
 
    private ParserFunction m_impl;
    private static Dictionary<string, ParserFunction> m_functions = new Dictionary<string, ParserFunction>();
 
    private static StrtodFunction s_strtodFunction = new StrtodFunction();
    private static IdentityFunction s_idFunction = new IdentityFunction();
  }
 
  class StrtodFunction : ParserFunction
  {
    protected override double evaluate(string data, ref int from)
    {
      double num;
      if (!Double.TryParse(Item, out num)) {
        throw new ArgumentException("Could not parse token [" + Item + "]");
      }
      return num;
    }
    public string Item { private get; set; }
  }
 
  class IdentityFunction : ParserFunction
  {
    protected override double evaluate(string data, ref int from)
    {
      return Parser.loadAndCalculate(data, ref from, Parser.END_ARG);
    }
  }
 
  class PiFunction : ParserFunction
  {
    protected override double evaluate(string data, ref int from)
    {
      return 3.141592653589793;
    }
  }
  class ExpFunction : ParserFunction
  {
    protected override double evaluate(string data, ref int from)
    {
      double arg = Parser.loadAndCalculate(data, ref from, Parser.END_ARG);
      return Math.Exp(arg);
    }
  }
  class PowFunction : ParserFunction
  {
    protected override double evaluate(string data, ref int from)
    {
      double arg1 = Parser.loadAndCalculate(data, ref from, ',');
      double arg2 = Parser.loadAndCalculate(data, ref from, Parser.END_ARG);
 
      return Math.Pow(arg1, arg2);
    }
  }
  class SinFunction : ParserFunction
  {
    protected override double evaluate(string data, ref int from)
    {
      double arg = Parser.loadAndCalculate(data, ref from, Parser.END_ARG);
      return Math.Sin(arg);
    }
  }
  class SqrtFunction : ParserFunction
  {
    protected override double evaluate(string data, ref int from)
    {
      double arg = Parser.loadAndCalculate(data, ref from, Parser.END_ARG);
      return Math.Sqrt(arg);
    }
  }
  class AbsFunction : ParserFunction
  {
    protected override double evaluate(string data, ref int from)
    {
      double arg = Parser.loadAndCalculate(data, ref from, Parser.END_ARG);
      return Math.Abs(arg);
    }
  }
но проблема вот в чем
как я поняла это описывается отдельный класс
но как его переделать на язык си шарп и как связать эти два кусочка не понимаю
может кто то подскажет ??или порекомендует что то другое для ввода для ввода функции через текстбокс??
Dasha111 вне форума   Ответить с цитированием

Старый 28.04.2017, 23:20
Helpmaster
Member
 
Аватар для Helpmaster
 
Регистрация: 08.03.2016
Сообщений: 0

Проблему решать гораздо легче, если набраться информации из схожих тем

PowerPoint-2007 преобразование в слайде TextBox в Title
Ввод цифр

Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.




Часовой пояс GMT +4, время: 19:40.

Powered by vBulletin® Version 6.2.5.
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.