2008-12-08 27 views
7

tốt nhất là gì là để đánh giá một biểu thức như sau:
(A và B) Hoặc (A và C) Hoặc (Không B Và C)
hoặc
(A & & B) || (A & & C) || (! B & & C)
Phân tích/đánh giá biểu thức logic động trong C# hoặc VB?

Khi chạy, tôi đã lên kế hoạch về chuyển đổi các biểu thức trên như sau:
(True và False) Hoặc (True và False) Hoặc (Không False Và True)
hoặc
(True & & Sai) || (Đúng & & Sai) || (! False & & True)

Điều kiện: 1) Biểu thức logic không được biết cho đến khi chạy. 2) Biến số và giá trị của chúng không được biết cho đến khi chạy. 3) Các giá trị biến không bao giờ là rỗng.

Tôi biết tôi có thể tạo ra một cách đơn giản lắp ráp với một lớp và một phương pháp mà tôi tạo ra khi chạy dựa trên các đầu vào, nhưng có cách nào tốt hơn. Tôi đã làm điều này trước đây. Sử dụng trình tạo chuỗi để viết mã, sau đó gọi trình biên dịch. Sau đó, bạn nạp assembly và gọi phương thức.

Đề xuất?

Cảm ơn.

+0

Bạn đang cố gắng để thực hiện? Bạn có thể chia sẻ cách bạn đang đến với các so sánh không? Điều này trông giống như một cái gì đó mà có thể được tiếp cận tốt hơn một cách khác nhau. –

+0

Trông giống như một danh sách những thứ cần so sánh. Bạn có thể lặp lại danh sách, và phá vỡ khi bạn thấy rằng bất kỳ hai là đúng sự thật. –

+0

Bạn có thể viết một trình phân tích cú pháp Logic theo đề xuất đơn giản ... Tôi nhớ phải làm một để giải quyết vấn đề Wumpus World. –

Trả lời

7

Nếu bạn đang sử dụng .NET3.5 thì bạn có thể phân tích cú pháp văn bản và tạo cây sytax trừu tượng bằng cách sử dụng các lớp biểu thức. Sau đó tạo một cá thể LambdaExpression phù hợp và biên dịch nó thành một đại biểu, sau đó bạn có thể thực hiện.

Xây dựng trình tạo cú pháp và cú pháp cho loại ngữ pháp khá đơn giản này là một bài tập khá thú vị, và sẽ thực thi nhanh hơn một chút so với việc gọi trình biên dịch (và nó cũng nằm trong khung nhìn của tôi).

Nếu bạn không sử dụng .NET3.5, thì cũng không phức tạp khi tự mình triển khai cây cú pháp trừu tượng được diễn giải.

+3

Bạn có thể đưa ra một ví dụ không. –

+4

Một liên kết hoặc ví dụ có thể hữu ích. – bernhof

0

Bạn có thể viết trình thông dịch/phân tích cú pháp đơn giản. Sử dụng một cái gì đó như ANTLR và sử dụng lại các ngữ pháp hiện có.

4

Được cảnh báo: hai điều kiện cuối cùng mà bạn đang nói đến không nhất thiết phải tương đương. Các toán tử & & trong C# sẽ sử dụng đánh giá ngắn mạch, trong khi toán tử logic And trong VB thì không. Nếu bạn muốn chắc chắn các câu tương tự, hãy dịch người dùng And thành AndAlso và người dùng Or đến OrElse.

Để thể hiện đơn giản, có thể bạn sẽ không nhận thấy sự khác biệt. Nhưng nếu các điều kiện có thể có tác dụng phụ hoặc nếu sự khác biệt hiệu suất giữa hai là một mối quan tâm, điều này có thể là quan trọng.

+0

Bất kể chúng có ngắn mạch hay không, kết quả của biểu thức là như nhau. Sự khác biệt duy nhất là khi A, B, C là các hàm và các hiệu ứng mạch ngắn cho dù chúng có được gọi hay không, nó không ảnh hưởng đến kết quả cuối cùng của biểu thức. – Kibbee

+0

@Kibbee - nhưng nó có thể ảnh hưởng đến kết quả cuối cùng của hệ thống * nếu tác dụng phụ có liên quan. –

0

Nếu bạn đang sử dụng .NET 3.5, bạn có thể tạo biểu thức Lambda. Sau đó, bạn có thể tạo một đại biểu từ nó và gọi như là đại biểu tiêu chuẩn/phương pháp. Trên internet là rất nhiều mẫu về Biểu thức Lambda.

-1

Một giải pháp sẽ là lắp ráp biểu thức dưới dạng chuỗi và sau đó gửi SQL Server hoặc bất kỳ cơ sở dữ liệu nào của bạn để đánh giá. Thay thế các biến thực tế bằng 1 = 1 hoặc 0 = 1 cho True và False tương ứng và bạn sẽ kết thúc bằng truy vấn như sau:

SELECT 1 WHERE (1 = 1 And 0 = 1) Hoặc (1 = 1) Và 1 = 1) Hoặc (Không 0 = 1 Và 1 = 1)

Sau đó, khi bạn chạy truy vấn, bạn nhận được 1 trở lại khi kết quả là đúng. Có thể không phải là giải pháp thanh lịch nhất, nhưng nó sẽ hoạt động. Rất nhiều người có thể sẽ khuyên bạn nên chống lại điều này, nhưng tôi sẽ ném nó ra ngoài như một giải pháp có thể.

+6

-1: Không khuyến khích mọi người viết các tin nhắn như thế này, đặc biệt là trong mã phát hành. – Juliet

+0

Một ý tưởng thú vị của nó. Bạn có thể xoay nó dễ dàng hơn bằng cách sử dụng phiên bản nhúng của máy chủ sql, thay vì dựa vào cài đặt đầy đủ. Thỉnh thoảng, hacks như thế này có thể cứu được mông của bạn. +1 – Will

3

Bạn có thể làm điều này một cách dễ dàng với:

  1. một máy phát điện phân tích cú pháp (như ANTLR, đã đề cập ở trên) mà sẽ đưa biểu thức boolean như là đầu vào và tạo ra một danh sách ghi vào và
  2. mã để đánh giá một Reverse Notation chồng Ba Lan .

Ngữ pháp trông giống như sau:

program: exprList ; 

exprList: expr { Append($1); } 
    | expr OR exprList { Append(OR); } 
    | expr AND exprList { Append(AND); } 
    | NOT exprList { Append(NOT); } 
    | (exprList) { /* Do nothing */ } 
    ; 

expr: var { Append($1); } 
    | TRUE { Append(True); } 
    | FALSE { Append(False); } 
    ; 

Để đánh giá, bạn làm như sau:

for each item in list 
    if item is symbol or truth value, push onto RPN stack 
    else if item is AND, push (pop() AND pop()) 
    else if item is OR, push (pop() OR pop()) 
    else if item is NOT, push (NOT pop()) 

result = pop() 

Đối với các biểu tượng, bạn cần phải thay thế các giá trị thật khi chạy.

3

Bạn có thể sử dụng https://github.com/mrazekv/logicalparser

của nó chỉ đơn giản là thư viện để viết biểu thức logic (evaulated với bảng precenednce, cho phép OR, NOT, AND điều hành và>,> =, < =, < trên các biến số nguyên và = on chuỗi biến)

0

Đây sẽ không phải là câu trả lời hay nhất, nhưng bản thân tôi đã gặp vấn đề này một thời gian trước đây.

Đây là mã cũ của tôi: VB.Net - không có bảo hành nào cả!

https://cloud.downfight.de/index.php/s/w92i9Qq1Ia216XB

Dim BoolTermParseObjekt As New BoolTermParse 
MsgBox(BoolTermParseObjekt.parseTerm("1 und (((0 oder 1 und (0 oder 4))) oder 2)").ToString) 

Mã này ăn một String với nhiều '(', ')', 'và', 'hoặc' cộng 'những thứ khác' và phá vỡ logic để một boolean bằng cách thay thế những thứ có giá trị boolean. do đó:

Bất cứ điều gì khác 'tôi muốn đánh giá tôi phải đặt trong Function resolveTerm() tại nhận xét "' funktionen ausführen und zurückgeben, einzelwert!" ở trang 2. Có những RightNow đánh giá chỉ là "Nếu con số là> 1"

Greetings

Các vấn đề liên quan