作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 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/
我的代码遇到了很大的困难。我正在开发一个显示歌词和和弦的应用程序。我使用两个重叠的textview分隔了和弦和歌词。 我在这个项目中遇到的问题是音高改变功能。我尽我所能向我解释得更好: 和弦总数为12
我有一个游戏并使用 Tune 作为分析库。使用最新的 Unity (5.3.4f1) 并通过 Unity 获取 apk(无 eclipse/android studio)。 我的游戏在 Play 商店
我是一名优秀的程序员,十分优秀!