后知后觉,chatgpt刚出来的时候就是简单测试一下聊天什么的,刚想起是不是能用来写一点稍微复杂一点的程序。
提示词:用c#语言实现加法、减法、乘法、除法四则运算,并支持有括号优先级以及负数的表达式解析器,优先级运算是按照括号、乘除法、加减法的先后顺序执行,例如:1+2-3/(3-1)*3+1=-0.5。
向gpt提问,系统给出答案如下,蓝色的是我微调了一下,总共不用30分钟,如果自己写这程序调试,以前的话怎么说也要1整天:
public class ExpressionResolver
{
public static double ResolveExpression(string expression)
{
return EvaluateExpression(FormatExpression(expression));
}
private static string FormatExpression(string expression)
{
// Remove spaces and normalize negative signs
expression = expression.Replace(" ", "");
// Normalize negative signs (e.g., "2*(-3)" becomes "2*(0-3)")
expression = NormalizeNegatives(expression);
return expression;
}
private static string NormalizeNegatives(string expression)
{
// If there's a negative sign after an operator or opening parenthesis,
// convert it to a subtraction from zero.
char[] operators = { '+', '-', '*', '/' };
bool f = false;
for (int i = 0; i < expression.Length; i++)
{
if (expression[i] == '-' && (i == 0 || expression[i - 1] == '(' || Array.Exists(operators, op => op == expression[i - 1])))
{
for (int i0 = i+1; i0 < expression.Length; i0++)
{
if (Array.Exists(operators, op => op == expression[i0]))
{
expression = expression.Substring(0, i) + "(0" + expression.Substring(i,i0-i)+ ")" + expression.Substring(i0);
i += i0 - i + 3;
f = true;
break;
}
}
if(!f)
{
expression = expression.Substring(0, i) + "(0" + expression.Substring(i) + ")";
i += 2;
}
// Skip past the inserted "(0"
}
}
return expression;
}
private static double EvaluateExpression(string expression)
{
Stack<double> operands = new Stack<double>();
Stack<char> operators = new Stack<char>();
for (int i = 0; i < expression.Length; i++)
{
if (expression[i] == '(')
{
operators.Push(expression[i]);
}
else if (expression[i] == ')')
{
while (operators.Peek() != '(')
{
EvaluateTop(operands, operators);
}
operators.Pop(); // Discard '('
}
else if (IsOperator(expression[i]))
{
while (operators.Count > 0 && operators.Peek() != '(' && Precedence(operators.Peek()) >= Precedence(expression[i]))
{
EvaluateTop(operands, operators);
}
operators.Push(expression[i]);
}
else
{
// Read operand
string operand = "";
while (i < expression.Length && (char.IsDigit(expression[i]) || expression[i] == '.'))
{
operand += expression[i];
i++;
}
i--; // Backtrack one position
operands.Push(double.Parse(operand, CultureInfo.InvariantCulture));
}
}
while (operators.Count > 0)
{
EvaluateTop(operands, operators);
}
return operands.Peek();
}
private static void EvaluateTop(Stack<double> operands, Stack<char> operators)
{
double b = operands.Pop();
double a = operands.Pop();
char op = operators.Pop();
double result = PerformOperation(a, b, op);
operands.Push(result);
}
private static double PerformOperation(double a, double b, char op)
{
switch (op)
{
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/':
if (b == 0)
{
throw new DivideByZeroException("Cannot divide by zero");
}
return a / b;
default: throw new ArgumentException("Invalid operator");
}
}
private static bool IsOperator(char c)
{
return c == '+' || c == '-' || c == '*' || c == '/';
}
private static int Precedence(char op)
{
switch (op)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default:
return 0;
}
}
}