前缀，中缀，后缀表达式学习笔记(2)

2012-05-03 15:51  MichaelYin  阅读(501)  评论(0编辑  收藏  举报

public static int Evaluate(char[] exp, int firstIndex, int lastIndex)
{
    //外层如果是括号则去掉
    if (exp[firstIndex] == '(' && exp[lastIndex] == ')')
    {
        return Evaluate(exp, firstIndex + 1, lastIndex - 1);
    }
    //进行计算
    int position = 0;
    char result = AddOrSub(exp, firstIndex, lastIndex, ref position);
    if (result != '#')
    {
        //计算
        if (result == '+')
        {
            return Evaluate(exp, firstIndex, position - 1) + Evaluate(exp, position + 1, lastIndex);
        }
        if (result == '-')
        {
            return Evaluate(exp, firstIndex, position - 1) - Evaluate(exp, position + 1, lastIndex);
        }
    }

    result = MultiplyOrDevide(exp, firstIndex, lastIndex, ref position);
    if (result != '#')
    {
        //计算
        if (result == '*')
        {
            return Evaluate(exp, firstIndex, position - 1) * Evaluate(exp, position + 1, lastIndex);
        }
        if (result == '/')
        {
            return Evaluate(exp, firstIndex, position - 1) / Evaluate(exp, position + 1, lastIndex);
        }
    }
    //生成实际数字值
    if (exp[firstIndex] > '9' || exp[firstIndex] < '0')
        Console.WriteLine("Error");

    return RealNum(exp[firstIndex]);
}

public static char AddOrSub(char[] exp, int firstIndex, int lastIndex, ref int position)
{
    System.Collections.Stack objStack = new Stack();
    //找到返回操作符，找不到返回#
    for (int i = firstIndex; i <= lastIndex; i++)
    {
        if (exp[i] == '(')
        {
            objStack.Push('(');
        }
        if (exp[i] == ')')
        {
            objStack.Pop();
        }
        if (exp[i] == '+' && objStack.Count == 0)
        {
            position = i;
            return '+';
        }
        if (exp[i] == '-' && objStack.Count == 0)
        {
            position = i;
            return '-';
        }
    }
    //没有找到对应的操作符
    return '#';
}

public static char MultiplyOrDevide(char[] exp, int firstIndex, int lastIndex, ref int position)
{
    //找到返回操作符，找不到返回#
    System.Collections.Stack objStack = new Stack();
    //找到返回操作符，找不到返回#
    for (int i = firstIndex; i <= lastIndex; i++)
    {
        if (exp[i] == '(')
        {
            objStack.Push('(');
        }
        if (exp[i] == ')')
        {
            objStack.Pop();
        }
        if (exp[i] == '*' && objStack.Count == 0)
        {
            position = i;
            return '*';
        }
        if (exp[i] == '/' && objStack.Count == 0)
        {
            position = i;
            return '/';
        }
    }
    //没有找到对应的操作符
    return '#';
}

public static int RealNum(char num)
{
    return 0 + (num - '0');
}

public static void EvaluateExpression()
  {
      System.Collections.Stack stackA = new System.Collections.Stack();
      System.Collections.Stack stackB = new System.Collections.Stack();
      stackA.Push('#');
      char user;
      user = (char)Console.Read();
      while (user != '#' || ((char)stackA.Peek() != '#'))
      {
          //操作符号
          if (In(user))
          {
              //判断优先级
              switch (Precede((char)stackA.Peek(), user))
              {
                  case '>':
                      //顺序
                      char b = (char)stackB.Pop();
                      char a = (char)stackB.Pop();
                      char op = (char)stackA.Pop();

                      stackB.Push(Operate(a, b, op));

                      break;
                  case '=':
                      stackA.Pop();
                      user = (char)Console.Read();
                      break;
                  case '<':
                      stackA.Push(user);
                      user = (char)Console.Read();
                      break;
              }
          }
          else
          {
              if (user < '0' || user > '9')
              {
                  Console.WriteLine("Error");
                  return;
              }
              else
              {
                  stackB.Push(user);
                  user = (char)Console.Read();
              }
          }

      }
      Console.WriteLine((char)stackB.Pop());
      Console.ReadLine();
  }

  /// <summary>
  /// 如果是操作符号，则返回true
  /// </summary>
  /// <param name="c"></param>
  /// <returns></returns>
  public static bool In(char c)
  {
      //该写法值得商榷
      switch (c)
      {
          case '(':
              return true;
          case ')':
              return true;
          case '+':
              return true;
          case '-':
              return true;
          case '*':
              return true;
          case '/':
              return true;
          case '#':
              return true;
      }
      return false;
  }

  public static char Precede(char t1, char t2)
  {
      char f = '=';
      switch (t2)
      {
          case '+':
          case '-': if (t1 == '(' || t1 == '#')
                  f = '<';
              else
                  f = '>';
              break;
          case '*':
          case '/': if (t1 == '*' || t1 == '/' || t1 == ')')
                  f = '>';
              else
                  f = '<';
              break;
          case '(': if (t1 == ')')
              {
                  Console.WriteLine("error");
              }
              else
                  f = '<';
              break;
          case ')':
              switch (t1)
              {
                  case '(': f = '=';
                      break;
                  case '#':
                      break;
                  default: f = '>';
                      break;
              }
              break;
          case '#': switch (t1)
              {
                  case '#': f = '=';
                      break;
                  case '(':
                      break;
                  default: f = '>';
                      break;
              }
              break;
      }
      return f;
  }

  public static char Operate(char a, char b, char operate)
  {
      a = Convert.ToChar((int)a - 48);
      b = Convert.ToChar((int)b - 48);
      int c = 0;
      switch (operate)
      {
          case '+': c = a + b + 48;
              break;
          case '-': c = a - b + 48;
              break;
          case '*': c = a * b + 48;
              break;
          case '/': c = a / b + 48;
              break;
      }
      return Convert.ToChar(c);
  }
  #endregion