基于上述文法,用wpf实现 A、中缀式错误检查:给出错误信息与错误位置 B、中缀式翻译为逆波兰式:给出翻译后的逆波兰式 C、逆波兰式的求值:执行逆波兰式并给出求值结果,系统要设计GUI,操作友好,给出具体代码
时间: 2024-03-24 18:40:53 浏览: 55
WPF多种验证方式
以下是一个用 C# 和 WPF 实现的计算器程序,可以进行中缀式错误检查、中缀式转换为逆波兰式和逆波兰式求值,同时具有友好的 GUI 界面。
MainWindow.xaml:
```xml
<Window x:Class="Calculator.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Calculator" Height="350" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox x:Name="InputBox" Grid.Row="0" Margin="5"/>
<StackPanel Grid.Row="1" Margin="5" Orientation="Horizontal">
<Button x:Name="ButtonCheck" Content="Check"/>
<Button x:Name="ButtonTranslate" Content="Translate"/>
<Button x:Name="ButtonEvaluate" Content="Evaluate"/>
</StackPanel>
<TextBlock x:Name="OutputBlock" Grid.Row="2" Margin="5" TextWrapping="Wrap"/>
</Grid>
</Window>
```
MainWindow.xaml.cs:
```csharp
using System;
using System.Collections.Generic;
using System.Windows;
namespace Calculator
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ButtonCheck.Click += ButtonCheck_Click;
ButtonTranslate.Click += ButtonTranslate_Click;
ButtonEvaluate.Click += ButtonEvaluate_Click;
}
private void ButtonCheck_Click(object sender, RoutedEventArgs e)
{
string input = InputBox.Text;
int pos = CheckInput(input);
if (pos == -1)
{
OutputBlock.Text = "Input is valid.";
}
else
{
OutputBlock.Text = $"Error at position {pos}.";
}
}
private void ButtonTranslate_Click(object sender, RoutedEventArgs e)
{
string input = InputBox.Text;
string output = TranslateInput(input);
OutputBlock.Text = output;
}
private void ButtonEvaluate_Click(object sender, RoutedEventArgs e)
{
string input = InputBox.Text;
string rpn = TranslateInput(input);
double result = EvaluateRPN(rpn);
OutputBlock.Text = result.ToString();
}
private int CheckInput(string input)
{
int pos = -1;
int depth = 0;
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (c == '(')
{
depth++;
}
else if (c == ')')
{
depth--;
if (depth < 0)
{
pos = i;
break;
}
}
else if (IsOperator(c))
{
if (i == 0 || i == input.Length - 1)
{
pos = i;
break;
}
char prev = input[i - 1];
char next = input[i + 1];
if (IsOperator(prev) || IsOperator(next))
{
pos = i;
break;
}
}
else if (!IsDigit(c) && c != ' ')
{
pos = i;
break;
}
}
if (depth != 0)
{
pos = input.Length - 1;
}
return pos;
}
private string TranslateInput(string input)
{
Stack<char> operatorStack = new Stack<char>();
List<string> outputList = new List<string>();
string number = "";
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (IsDigit(c))
{
number += c;
}
else if (c == ' ')
{
if (number != "")
{
outputList.Add(number);
number = "";
}
}
else if (IsOperator(c))
{
if (number != "")
{
outputList.Add(number);
number = "";
}
while (operatorStack.Count > 0 && operatorStack.Peek() != '(' && GetPriority(operatorStack.Peek()) >= GetPriority(c))
{
outputList.Add(operatorStack.Pop().ToString());
}
operatorStack.Push(c);
}
else if (c == '(')
{
if (number != "")
{
outputList.Add(number);
number = "";
}
operatorStack.Push(c);
}
else if (c == ')')
{
if (number != "")
{
outputList.Add(number);
number = "";
}
while (operatorStack.Count > 0 && operatorStack.Peek() != '(')
{
outputList.Add(operatorStack.Pop().ToString());
}
operatorStack.Pop();
}
}
if (number != "")
{
outputList.Add(number);
}
while (operatorStack.Count > 0)
{
outputList.Add(operatorStack.Pop().ToString());
}
string output = string.Join(" ", outputList);
return output;
}
private double EvaluateRPN(string rpn)
{
Stack<double> stack = new Stack<double>();
string[] tokens = rpn.Split(' ');
foreach (string token in tokens)
{
if (IsDigit(token[0]))
{
double value = double.Parse(token);
stack.Push(value);
}
else
{
double b = stack.Pop();
double a = stack.Pop();
double result = 0;
if (token == "+")
{
result = a + b;
}
else if (token == "-")
{
result = a - b;
}
else if (token == "*")
{
result = a * b;
}
else if (token == "/")
{
result = a / b;
}
stack.Push(result);
}
}
double finalResult = stack.Pop();
return finalResult;
}
private bool IsDigit(char c)
{
return c >= '0' && c <= '9';
}
private bool IsOperator(char c)
{
return c == '+' || c == '-' || c == '*' || c == '/';
}
private int GetPriority(char c)
{
if (c == '+' || c == '-')
{
return 1;
}
else if (c == '*' || c == '/')
{
return 2;
}
else
{
return 0;
}
}
}
}
```
该程序实现了三个操作:中缀式错误检查、中缀式转换为逆波兰式和逆波兰式求值。在 MainWindow.xaml 中定义了一个文本框用于输入表达式,三个按钮分别对应不同的操作,一个文本块用于显示输出结果。在 MainWindow.xaml.cs 中实现了具体的操作逻辑,包括中缀式错误检查、中缀式转换为逆波兰式和逆波兰式求值的实现。其中,中缀式转换为逆波兰式使用了栈来辅助实现,逆波兰式求值也使用了栈来辅助实现。
阅读全文