Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何正确组合多个布尔后缀表达式?_.net_Vb.net_Binary Tree_Postfix Notation_Rpn - Fatal编程技术网

.net 如何正确组合多个布尔后缀表达式?

.net 如何正确组合多个布尔后缀表达式?,.net,vb.net,binary-tree,postfix-notation,rpn,.net,Vb.net,Binary Tree,Postfix Notation,Rpn,我编写了一些代码,可以在后缀和中缀之间进行转换,然后再转换回来。现在我试着把不同的后缀表达式组合起来 我的表达式仅使用布尔运算符(NOT、XOR和或) 请注意,表达式中的数字指的是最终计算为true或false的规则 目前,我遇到了组合表达式时出现的问题,这些表达式中没有 例如,我想使用AND将以下内容组合成一个后缀表达式: 45 46 & 1 ! 41 42 | 48 | 50 51 | 目前,我的输出如下所示: 45 46 & 1 ! & 50 51 | &

我编写了一些代码,可以在后缀和中缀之间进行转换,然后再转换回来。现在我试着把不同的后缀表达式组合起来

我的表达式仅使用布尔运算符(NOT、XOR和或)

请注意,表达式中的数字指的是最终计算为true或false的规则

目前,我遇到了组合表达式时出现的问题,这些表达式中没有

例如,我想使用AND将以下内容组合成一个后缀表达式:

45 46 &
1 !
41 42 | 48 |
50 51 |
目前,我的输出如下所示:

45 46 & 1 ! & 50 51 | & 41 42 | 48 | & 
但是当把它转换成中缀时,我(错误地)得到了这个(注意前导&):

我不确定这是用于组合表达式的代码的不足,还是后缀到中缀转换的不足

对于上面前四个表达式的ANDed组合,正确的后缀表达式是什么

我怀疑我的问题是在转换或组合例程(或两者)中没有正确处理not运算符

下面是组合代码,后面是转换代码

组合:

Public Shared Function GetExpandedExpression(Expressions As List(of String)) As String
    'there is guaranteed to be at least one item in the list.
    ExpandedPostfixExpression = PostfixList(0) & " "
    If PostfixList.Count > 1 Then
        For i As Integer = 1 To PostfixList.Count - 1
            ExpandedPostfixExpression &= PostfixList(i) & " & "
        Next
    End If

    Return ExpandedPostfixExpression.TrimEnd
End Function
转换:

Public Class ExpressionConversion

    Private Class Intermediate
        Public expr As String
        Public oper As String
        Public Sub New(expr As String, oper As String)
            Me.expr = expr
            Me.oper = oper
        End Sub
    End Class

    Private Const Operators As String = "!&|*()"

    Private Shared Function IsOperator(elem As String) As Boolean
        Return Operators.Contains(elem)
    End Function

    Public Shared Function PostfixToInfix(postfix As String) As String
        'Adapted from http://www.codeproject.com/Articles/405361/Converting-Postfix-Expressions-to-Infix
        Dim stack = New Stack(Of Intermediate)()
        For Each token As String In postfix.Split(CChar(" "))
            If IsOperator(token) Then
                ' Get the intermediate expressions from the stack.  
                ' If an intermediate expression was constructed using a lower precedent
                ' operator (+ or -), we must place parentheses around it to ensure 
                ' the proper order of evaluation.
                Dim leftExpr As String = ""
                Dim rightExpr As String = ""

                Dim rightIntermediate = stack.Pop()
                If rightIntermediate.oper <> "" AndAlso Precedence(token) >= Precedence(rightIntermediate.oper) Then
                    rightExpr = "( " + rightIntermediate.expr + " )"
                Else
                    rightExpr = rightIntermediate.expr
                End If

                If stack.Count <> 0 Then 'in the case where there is only a unary op eg NOT - skip the following
                    Dim leftIntermediate = stack.Pop()
                    If leftIntermediate.oper <> "" AndAlso Precedence(token) >= Precedence(leftIntermediate.oper) Then
                        leftExpr = "( " + leftIntermediate.expr + " )"
                    Else
                        leftExpr = leftIntermediate.expr
                    End If
                End If
                ' construct the new intermediate expression by combining the left and right 
                ' using the operator (token).
                Dim newExpr = (leftExpr & " " & token & " " & rightExpr).Trim

                ' Push the new intermediate expression on the stack
                stack.Push(New Intermediate(newExpr, token))
            Else
                stack.Push(New Intermediate(token, ""))
            End If
        Next

        ' The loop above leaves the final expression on the top of the stack.
        Return stack.Peek().expr
    End Function

    Private Shared Function Precedence(op As String) As Integer
        Select Case op
            Case "!"
                Return 4
            Case "*"
                Return 3
            Case "&"
                Return 2
            Case "|"
                Return 1
        End Select
        Return 0
    End Function
End Class
公共类表达式转换
私立中级中学
公共表达式为字符串
公共歌剧字符串
Public Sub New(expr As String、oper As String)
Me.expr=expr
Me.oper=oper
端接头
末级
私有常量运算符为String=“!&|*()”
作为布尔值的专用共享函数等运算符(元素为字符串)
返回运算符.Contains(elem)
端函数
公共共享函数postfix(postfix作为字符串)作为字符串
"改编自http://www.codeproject.com/Articles/405361/Converting-Postfix-Expressions-to-Infix
尺寸堆栈=新堆栈(中间)()
对于postfix.Split(CChar(“”)中作为字符串的每个标记
如果是等运算符(标记),则
'从堆栈中获取中间表达式。
'如果使用较低的先决条件构造中间表达式
'运算符(+或-),我们必须在其周围加括号以确保
正确的评估顺序。
Dim leftExpr As String=“”
Dim rightExpr As String=“”
Dim rightmediate=stack.Pop()
如果rightIntermediate.oper“”和其他优先级(标记)>=优先级(rightIntermediate.oper),则
rightExpr=“(“+rightIntermediate.expr+”)”
其他的
rightExpr=rightIntermediate.expr
如果结束
如果stack.Count为0,则在只有一元运算例如NOT的情况下,跳过以下内容
Dim leftmediate=stack.Pop()
如果leftIntermediate.oper“”和ALSO优先级(标记)>=优先级(leftIntermediate.oper),则
leftExpr=“(“+leftIntermediate.expr+”)”
其他的
leftExpr=leftIntermediate.expr
如果结束
如果结束
'通过组合左和右来构造新的中间表达式
'使用运算符(令牌)。
Dim newExpr=(leftExpr&&token&&righexpr)。修剪
'将新的中间表达式推送到堆栈上
stack.Push(新中间层(newExpr,token))
其他的
stack.Push(新的中间标记(“”))
如果结束
下一个
'上面的循环将最终表达式保留在堆栈顶部。
返回stack.Peek().expr
端函数
私有共享函数优先级(op为字符串)为整数
选择案例op
案例“!”
返回4
案例“*”
返回3
案例&
返回2
案例“|”
返回1
结束选择
返回0
端函数
末级
更新

以下是由标记答案导致的代码更改(在转换例程中):

替换此项:

If stack.Count <> 0 
如果堆栈计数为0
为此:

If stack.Count <> 0 And token <> "!"
If stack.Count 0和token”

如注释中所述,我认为如果表达式是一元运算符,则必须将其推回到堆栈上才能成为下一个RHS表达式。否则,下面的运算符也将被视为一元运算符,这将导致在前导中的情况&。

我想知道如果表达式是一元运算符,则是否必须将其推回堆栈才能再次成为下一轮RHS表达式,否则在您的情况下,下面的运算符也将被视为一元运算符,从而导致前导&.那是一张在黑暗中瞥了一眼的照片.那是一张极好的照片。如果你想把它写进一个答案,我很乐意把它标出来。
If stack.Count <> 0 And token <> "!"