英文:
Problem with decimal convertion in Math Expression Evaluator
问题
我正在使用C#实现一个数学表达式计算器,但无法使用十进制数,例如,如果我输入"3.4",程序会将其视为"34"。如果使用逗号如"3,4",问题也是一样的。
我已经尝试强制代码使用"en-US"的全球化,但没有成功。我还尝试了不同的解析方法,试图将字符串转换为浮点数,但也没有成功。
英文:
I'm implementing a math expression evaluator in C# but I has not able to use decimal numbers, like, if I enter "3.4" the program consider it as "34". The problem is the same if use coma like "3,4".
static void EvaluateInput(string input)
{
string[] parts = input.Split('=');
if (parts.Length == 2)
{
string variableName = parts[0].Trim();
if (IsValidVariableName(variableName))
{
string expression = parts[1].Trim();
double result = SolveExpression(expression);
variables[variableName] = SolveExpression(expression);
lastResult = result;
Console.WriteLine($"{variableName} = {result}");
}
else
{
Console.WriteLine("Invalid variable name. Use lowercase letters.");
}
}
else
{
double result = SolveExpression(input);
lastResult = result;
Console.WriteLine($" = {result}");
}
}
static bool IsValidVariableName(string variableName)
{
return !string.IsNullOrEmpty(variableName) && variableName.Length == 1 && char.IsLower(variableName[0]);
}
static double SolveExpression(string expression)
{
expression = expression.Replace(',', '.');
foreach (var constant in constants)
{
expression = expression.Replace(constant.Key, constant.Value.ToString(CultureInfo.InvariantCulture));
}
expression = Regex.Replace(expression, @"(?<=[^\d\.])-", "-");
expression = Regex.Replace(expression, @"(?<=\d)-", " -");
string[] tokens = TokenizeExpression(expression);
Stack<string> operators = new Stack<string>();
Stack<double> values = new Stack<double>();
foreach (string token in tokens)
{
if (double.TryParse(token, out double number))
{
values.Push(number);
}
else if (IsValidVariableName(token))
{
if (variables.ContainsKey(token))
{
values.Push(variables[token]);
}
else
{
throw new InvalidOperationException($"Undefined variable: {token}");
}
}
else if (IsOperator(token))
{
while (operators.Count > 0 && Priority(operators.Peek()) >= Priority(token))
{
if (operators.Peek() == "(")
break;
if (values.Count >= 2)
{
double val2 = values.Pop();
double val1 = values.Pop();
string op = operators.Pop();
values.Push(ApplyOperator(op, val1, val2));
}
else
{
break;
}
}
operators.Push(token);
}
else if (token == "(")
{
operators.Push(token);
}
else if (token == ")")
{
while (operators.Peek() != "(")
{
double val2 = values.Pop();
double val1 = values.Pop();
string op = operators.Pop();
values.Push(ApplyOperator(op, val1, val2));
}
operators.Pop();
}
}
while (operators.Count > 0)
{
if (values.Count >= 2)
{
double val2 = values.Pop();
double val1 = values.Pop();
string op = operators.Pop();
values.Push(ApplyOperator(op, val1, val2));
}
else
{
break;
}
}
return values.Count > 0 ? values.Pop() : 0;
}
static string[] TokenizeExpression(string expression)
{
List<string> tokens = new List<string>();
string currentToken = "";
for (int i = 0; i < expression.Length; i++)
{
char c = expression[i];
if (char.IsDigit(c) || c == '.' || c == ',')
{
currentToken += c;
}
else
{
if (!string.IsNullOrEmpty(currentToken))
{
if (double.TryParse(currentToken.Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out double parsedNumber))
{
tokens.Add(parsedNumber.ToString(CultureInfo.InvariantCulture));
}
else
{
tokens.Add(currentToken);
}
currentToken = "";
}
if (IsOperator(c.ToString()) || c == '(' || c == ')')
{
tokens.Add(c.ToString());
}
else if (char.IsLetter(c))
{
currentToken = c.ToString();
}
}
}
if (!string.IsNullOrEmpty(currentToken))
{
if (double.TryParse(currentToken.Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out double parsedNumber))
{
tokens.Add(parsedNumber.ToString(CultureInfo.InvariantCulture));
}
else
{
tokens.Add(currentToken);
}
}
return tokens.ToArray();
}
static bool IsOperator(string token)
{
return token == "+" || token == "-" || token == "*" || token == "/" || token == "^";
}
static int Priority(string op)
{
if (op == "^")
return 3;
if (op == "*" || op == "/")
return 2;
if (op == "+" || op == "-")
return 1;
return 0;
}
static double ApplyOperator(string op, double a, double b)
{
switch (op)
{
case "+": return a + b;
case "-": return a - b;
case "*": return a * b;
case "/": return a / b;
case "^": return Math.Pow(a, b);
default: throw new ArgumentException($"Invalid operator: {op}");
}
}
I have tried to force the code to use "en-US" globalization but I no success. I also tried difference parses in sense to convert the string to a float number, also not succeed
答案1
得分: 0
尝试这样做:
if (new Regex(@"\d+(\.\d+)?").IsMatch(token))
{
values.Push(double.Parse(token, CultureInfo.InvariantCulture));
}
其他的 TryParse
也可能需要更改。
英文:
Instead of doing:
if (double.TryParse(token, out double number))
{
values.Push(number);
}
try this:
if (new Regex(@"\d+(\.\d+)?").IsMatch(token))
{
values.Push(double.Parse(token, CultureInfo.InvariantCulture));
}
Other TryParse
s might also need changing.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论