具有三角函数的调车场算法

编程入门 行业动态 更新时间:2024-10-16 16:12:01
本文介绍了具有三角函数的调车场算法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正致力于在 C# 中实现调车场算法.虽然它用符号(+、*-/和 ^)解析数学表达式非常好.但由于某种原因它不适用于正弦余弦函数.例如,如果我尝试计算 sin(45) 我得到 0.707106 .但是当我尝试解析像

I am working on implementing shunting yard algorithm in C#. Although it parses mathematical expressions with symbols( + , * - / and ^) pretty well.But for some reason it is not working for sine cosine functions . Like for example if I try to calculate sin(45) I get 0.707106 . But when I try to parse expression like

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)

我已按照本文维基百科中提到的所有步骤进行操作.我已经尝试了几天,但我无法让它完美地工作.这里是主要的解析函数

I have followed all the steps that are mentioned in this article at Wikipedia . I have trying this for a few days now but I am unable to make it work perfectly. Here is the main parsing function

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()); } } } } }

此外,这是程序的输出:

Moreover, Here is the output of the program:

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

仅此而已.谁能指出我做错了什么.

Thats all.Can anybody point me what I am doing wrong.

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

Here is the IsHigherPrecedance function and precedance enum :

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; }

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

Now that these trigonometric function are single argument function, are they going to be parsed with some other logic or does this shunting yard algo works with such functions as well as well?

问候.

推荐答案

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

There are a copule of problems here, but the primary one is that you are treating functions as operators, though they are not (intrinsic to this is that you call your stack "operators" as though that is the only thing that can be on it, not true). In particular, this branch:

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"堆栈上的内容是否实际上是一个运算符:

needs to check to see if what's on the "operators" stack is actually an operator:

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])); }

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

Other issues include the branch that handles commas:

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() + " "; } }

更多推荐

具有三角函数的调车场算法

本文发布于:2023-11-29 12:13:02,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1646363.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:调车场   算法   函数

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!