gpt4 book ai didi

c# - 三角函数调车场算法

转载 作者:行者123 更新时间:2023-11-30 22:23:07 25 4
gpt4 key购买 nike

我正在使用 C# 实现调车场算法。虽然它能很好地解析带有符号(+、* -/和 ^)的数学表达式。但由于某些原因,它不适用于正余弦函数。例如,如果我尝试计算 sin(45) 我得到 0.707106 。但是当我尝试解析像

这样的表达式时
   sin(25)+cos(15+sin(25))+3  it gives me 0.43756   (Correct answer is: 2.19106879911)

    sin(45)+cos(45) it gives me 0.715779      (Correct answer is: 1.414)

我已按照本文 at Wikipedia 中提到的所有步骤进行操作.我已经尝试了几天了,但我无法让它完美地工作。下面是主要的解析函数

    private void parse()
{
//scan the input string
for (int j = 0; j < input.Length; j++)
{

if (Char.IsDigit(input[j])) //if its a number
{
string number = extractNumber(input, j); //extracts multiple digit number
j = currentposition; //increment the counter according to length of the digit
postfix += number + " ";
Console.WriteLine(postfix);
}
//if its a function character
else if(Char.IsLetter(input[j]) )
{
//its a letter
string function = getFunction(j); //get the function name
operators.Push( function );
j = currentposition;

}
else if(input[j] == ',') //if its a comma
{
while(operators.Peek() != "(")
{
postfix += input[j] + " ";

}

}
else if (IsAnOperator(input[j])) // if we have got an operator
{
if (operators.Count != 0 && IsHigherPrecedence(operators.Peek().ToCharArray()[0], input[j]))
{
while ( ( operators.Count != 0 && IsHigherPrecedence(operators.Peek().ToCharArray()[0], input[j]) ) )
{
postfix += operators.Pop() + " ";

}
}

operators.Push(Char.ToString(input[j]));
}
else if (input[j] == '(')
operators.Push(Char.ToString(input[j]));
else if (input[j] == ')')
{
while (operators.Count != 0 && operators.Peek() != "(")
postfix += operators.Pop() + " ";
operators.Pop();
}


} // end for loop

while(operators.Count > 0 )
postfix +=operators.Pop() + " ";

//Conversion Logic (postfix to final answer )

postfixtokens.AddRange( postfix.Split(' ') ) ;

for (int j = 0; j < postfixtokens.Count-1; j++)
{

if (IsAnOperator(postfixtokens[j][0]) && basket.Count > 1)
{

Double second = Double.Parse( basket.Pop() );

Double first = Double.Parse(basket.Pop() );
char op = postfixtokens[j][0];
Double result = ApplyOperation(op,second, first);
// Console.WriteLine("{0} {1} {2} = {3}", first, op, second, result);
basket.Push( result.ToString());
}
else if (IsAnOperator(postfixtokens[j][0]) && basket.Count == 1)
{

Double second = Double.Parse(basket.Pop());
Double first = 0.0;
char op = postfixtokens[j][0];

Double result = ApplyOperation(op, second, first);

// Console.WriteLine("{0} {1} {2} = {3}", first, op, second, result);
basket.Push(result.ToString() );
}
else if (Char.IsDigit(postfixtokens[j][0]))
{
basket.Push( postfixtokens[j] );
}
else if( isAFunction(postfixtokens[j]) )
{
//if its a single argument function
if (AllowedFunctions[postfixtokens[j]] == 1)
{
//single arg logic
if (postfixtokens[j] == "sin")
{
Double result = Math.Sin( Double.Parse(basket.Pop() )*Math.PI/180.0 );
//result = Math.PI / 180;
basket.Push(result.ToString());
}
else if (postfixtokens[j] == "cos")
{
Double result = Math.Cos( Double.Parse(basket.Pop() )*Math.PI/180.0 );
//result = Math.PI / 180;
basket.Push(result.ToString());
}

}

}
}
}

此外,这是程序的输出:

   Input: 3+4*2/(1-5)^5^10
PostFix: 3 4 2 * 1 5 - 5 10 ^ ^ / +
Answer: 3


Input: 2+4
PostFix: 2 4 +
Answer: 6

Input Expression: -5-4
Input: -5-4
PostFix: 5 - 4 -
Answer: -9

Input: -4+3
PostFix: 4 - 3 +
Answer: -1

Input Expression: 4^(4^4)
Input: 4^(4^4)
PostFix: 4 4 4 ^ ^
Answer: 1.34078079299426E+154

Input: sin45
PostFix: 45 sin
Answer: 0.707106781186547 (correct)

//错误的

   Input: sin(25)+cos(15+sin(25))+3
PostFix: 25 15 25 sin + 3 + cos + sin
Answer: 0.437567038002202

Input: sin(45)+cos(45)
PostFix: 45 45 cos + sin
Answer: 0.71577935734684

新案例:

    Input: sin45+cos45
PostFix: 45 45 cos + sin
Answer: 0.71577935734684

Input: 2+sin30
PostFix: 2 30 sin +
Answer:2.5

Input: sin30+2
PostFix: 30 2 + sin
Answer: 0.529919264233205

就是这样。谁能指出我做错了什么。

编辑:

这是 IsHigherPrecedance 函数和优先级枚举:

    public enum Precedance { Plus =1,Minus=1,Multiply=2,Divide=2,Exponent=3,Unary = 4,Parenthesis=5 };
private bool IsHigherPrecedence(char a, char b)
{
Precedance f = getPrecedance(a);
Precedance s = getPrecedance(b);


if (f >= s)
return false;
else
return true;
}
public Precedance getPrecedance(char a)
{

if (a == '+')
return Precedance.Plus;
else if (a == '-')
return Precedance.Minus;
else if (a == '*')
return Precedance.Multiply;
else if (a == '/')
return Precedance.Divide;
else if (a == '^')
return Precedance.Exponent;
else if (Char.IsLetter(a))
return Precedance.Unary;
else if (a == '(' || a == ')')
return Precedance.Parenthesis;
else
return Precedance.Plus;
}

既然这些三角函数是单参数函数,它们是否会用其他逻辑进行解析,或者这个调车场算法是否也适用于这些函数?

问候。

最佳答案

这里有很多问题,但最主要的是您将函数视为运算符,尽管它们不是(本质上是您将堆栈称为“运算符”,就好像这是唯一可以在上面,不是真的)。特别是,这个分支:

else if (IsAnOperator(input[j])) // if we have got an operator
{
if (operators.Count != 0 && IsHigherPrecedence(operators.Peek().ToCharArray()[0], input[j]))
{
while ( ( operators.Count != 0 && IsHigherPrecedence(operators.Peek().ToCharArray()[0], input[j]) ) )
{
postfix += operators.Pop() + " ";
}
}
operators.Push(Char.ToString(input[j]));
}

需要检查“operators”栈中的内容是否真的是一个操作符:

else if (IsAnOperator(input[j])) // if we have got an operator
{
while (operators.Count != 0
&& IsAnOperator(operators.Peek().ToCharArray()[0])
&& IsHigherPrecedence(operators.Peek().ToCharArray()[0], input[j]))
{
postfix += operators.Pop() + " ";
}
operators.Push(Char.ToString(input[j]));
}

其他问题包括处理逗号的分支:

else if (input[j] == ',') //if its a comma
{
while (operators.Peek() != "(")
{
// this isnt right, but its not the problem
postfix += input[j] + " ";
// should be this:
postfix += operators.Pop() + " ";
}

}

关于c# - 三角函数调车场算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13532309/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com