Tính biểu thức bất kì

Em đang viết một chương trình nhập một biểu thức vd: “4+5*6+7” trong c# nhưng em ko có ý tưởng để chuyển đỗi các dấu trong chuỗi để tính toán.Anh chị có ý tưởng ko ạ

Ý tưởng là regular expression:

  • Bước 1, với các phép + - * / sử dụng regex, tìm và thay thế biểu thức dạng a[*/]b bằng giá trị tương ứng. Tìm tiếp a[+ -]b và thay thế.
  • Bước 2, Đối với các biểu thức có dạng (expression) tức 1 cặp (). Tìm và thay thế bởi phép tính expression theo bước 1. Dùng đệ quy cho tới khi hết cặp (). expression phải là any but ).
  • Bước 3, với các hàm sin(expression), cos(expression), tan(expression), sqrt(expression), log(expression). Dùng regex tính toán expression theo bước 1 2 và 3(đệ quy). rồi tính sin, sqrt sau.Ở bước này có nhiều cách tính thay vì dùng switch.
  • Bước 4: Refactor code do bước 1,2,3 có thể gọi đệ quy qua lại lẫn nhau.

Dưới đây là code cho bước 1, chưa refactor.

Chỉ mở khi cần
static void Main(string[] args)
{
    string expression;                                         

    Console.Write("Nhap Expression: \r\n");
    expression = Console.ReadLine().Replace(" ","");
    Regex regex = new Regex(@"(\d+\.?\d*)+([\*\/])(\d+\.?\d*)");
    while (regex.IsMatch(expression))
    {
        var matches = regex.Matches(expression);
        MatchEvaluator myEvaluator = new MatchEvaluator(calculate);
        expression = regex.Replace(expression, myEvaluator);
    }
    regex = new Regex(@"(\d+\.?\d*)+([\+\-])(\d+\.?\d*)");
    while (regex.IsMatch(expression))
    {
        var matches = regex.Matches(expression);
        MatchEvaluator myEvaluator = new MatchEvaluator(calculate);
        expression = regex.Replace(expression, myEvaluator);
    }
    
    Console.WriteLine($"= {expression}");
    Console.ReadKey();
    Console.WriteLine();
}
private static string calculate(Match m)
{
    double val1 = Convert.ToDouble(m.Groups[1].Value);
    double val2 = Convert.ToDouble(m.Groups[3].Value);
    double value = 0;
    string sign = m.Groups[2].Value;
    switch (sign)
    {
        case "*":
        value = val1 * val2;
        break;
        case "/":
        value = val1 / val2;
        break;
        case "+":
        value = val1 + val2;
        break;
        case "-":
        value = val1 - val2;
        break;
        case "^":
        value = 1;
        for (int i = 0; i < (int)val2; i++)
        {
            value *= value;
        } 
        break;
        default:
        break;
    }
    return value.ToString();
}

Bạn cũng có thể tham khảo Microsoft Calculator. Nhưng viết bằng c++.

3 Likes

Hi Thịnh Cao Huy.

  1. Bạn cần kiểm tra kiểu dữ liệu của sâu và tách nó thành sô, toán tử, hàm v.v…
  2. Chuyển qua ký pháp Ba Lan dựa trên kiểu dữ liệu tree.
  3. Xây dựng các hàm cơ bản
  4. Tính toán tree bằng các hàm cơ bản đã dựng.
4 Likes
3 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?