Thuật toán tính giá trị biểu thức
Phương pháp nghịch đảo Balan hoặc cây biểu thức sẽ làm cho các bạn mới học lúng túng. Đây là một phương cực kỳ đơn giản các bạn có thể đọc hiểu và vận dụng được Biểu thức đơn giản bao gồm 2 phép toán + và * Vd: 2*5+3+4*3+2 Cách tính: Show Nếu trong biểu thức có phép + thì lấy phần biểu thức đầu + phần biểu thức cuối Ngược lại nếu trong biểu thức có phép * thì lấy phần đầu biểu thức * phần cuối biểu thức Ngược lại biểu thức = chính số đó Minh họa: “2*5+3+4*3+2” = “2*5″+”3+4*3+2” = 2*5+3+”4*3+2″= 2*5+3+”4*3″+2 = 2*5+3+4*3+2 Biểu thức bao gồm các phép toán +, -, * Trước khi tính biểu thức ta thêm vào dấu + trước mỗi dấu – (nếu có dấu – đứng đầu câu thì để nguyên) Tính toán bình thường như không có phép – Biểu thức bao gồm phép toán +, -, *, / Thêm + vào trước – Thêm * vào trước / Trong lúc đổi xâu thành số nếu có lỗi thì cắt bỏ ký tự đầu của xâu -> tiếp tục đổi xâu thành số và sau đó lấy nghịch đảo. Tiến hành tính toán bình thường như biểu thức chỉ có + và * Nếu bạn sử dụng giải thuật này trong bài viết bạn, làm ơn ghi rõ tên tác giả của giải thuật qvluom Code minh họa với 4 phép toán +, -, *, / #includeTrong một số bài viết trước đây tôi đã giới thiệu thuật toán chuyển đối biểu thức toán học giữa các dạng trung tố (infix), tiền tố (prefix) và hậu tố (postfix). Đồng thời tôi cũng trình bày phương pháp tính giá trị của các biểu thức này cũng như xây dựng cây biểu thức trực quan qua chương trình Y2 – Expression Converter Demo. Tuy nhiên thuật toán này chỉ mới hỗ trợ các toán tử hai ngôi (binary operation), trong bài viết này tôi sẽ mở rộng để thuật toán làm việc với các toán tử một ngôi (unary operation). Cập nhật (23 March 2011): Cảm ơn bạn ngngthanhmai đã góp ý về một số trường hợp lỗi với toán tử “-” (unary). Giới thiệuDo thời gian có hạn nên tôi chỉ minh họa với hai toán tử là “-“ (số âm) và “sqrt()” (căn bậc hai). Hai toán tử /hàm này có điểm chung là đứng trước toán hạng. Các toán tử đứng sau toán hạng như “!” (giai thừa) cũng có cơ chế xử lý tương tự. Đối với các toán tử (hoặc hàm) như sqrt, sin, cos,… có hai cách viết là đặt các toán hạng bên trong dấu ngoặc đơn hoặc không (ví dụ: sqrt(x) hoặc sqrt x). Ở đây tôi chọn cách đầu tiên để có thể đặt một biểu thức vào trong cặp ngoặc đơn và làm biểu thức rõ ràng hơn. Nội dung cập nhậtCác cập nhật sau nằm trong thư viện Y2ExprConverter.dll thuộc chương trình Y2-ExpressionConverter (version 1.2). Tôi chỉ sửa đổi một vài phương thức chuyển đổi và tính toán với postfix, tạo cây biểu thức từ infix. Các phương thức còn lại bạn có thể thực hiện tương tự. Tất cả các sửa đổi này đều được cập nhật đầy đủ mã nguồn và chức năng cho chương trình Y2-ExpressionConverter (version 1.2). Các phương thức chungSửa đổi phương thức định dạng biểu thức để xử lý các trường hợp nhập nhiều toán tử liền nhau (chỉ cho phép hai toán tử với toán tử thứ hai là “-“): Sửa đổi phương thức lấy độ ưu tiên và kiểm tra toán tử (bổ sung toán tử sqrt): public static int GetPriority(string op) { if (op == "sqrt") return 3; if (op == "*" || op == "/" || op == "%") return 2; if (op == "+" || op == "-") return 1; return 0; } public static bool IsOperator(string str) { return Regex.Match(str, @"^(\+|\-|\*|\/|\%|sqrt)$").Success; }Chuyển đổi từ biểu thức infix sang postfix– Khi gặp toán tử dấu âm “-“ (toán tử “-“ đứng liền sau toán tử khác), ta nối toán tử này với toán hạng ngay sau nó – Khi gặp toán tử “sqrt” ta push vào stack public static string Infix2Postfix(string infix) { infix = FormatExpression(infix); string[] tokens = infix.Split(' ').ToArray(); StackTính giá trị của biểu thức postfixTa chỉ lấy một toán hạng ra khỏi stack để tính thay vì hai toán hạng như đối với các toán tử binary public static double EvaluatePostfix(string postfix) { StackChuyển biểu thức infix thành cây biểu thứcprivate static void CreateSubTree(StackCác đoạn mã nguồn trên được trích từ tập tin Y2Expression.cs trong thư viện Y2ExprConverter.dll. Bạn có thể xem mã nguồn hoàn chỉnh của tập tin này tại link sau: C# – Y2Expression: Convertion, Evaluation and Build Expression Tree https://yinyangit.wordpress.com |