1.随机表达式,如:(221.05 + 619.48) * ((221.05 + 619.48)) * ((221.05 + 619.48) * ((221.05 + 619.48)));
Test:
/// <summary>
///A test for BuildRandom expression
///</summary>
[TestMethod()]
public void BuildRandomExpression_simple_Test()
{
Expression target = new Expression();
BinTree<string> tree = new BinTree<string>();
int opCount = 5;
BinTree<ExpressionItem> actual;
string re = target.BuildRandom(opCount);
double d = tree.Calculate(re);
}
implementation:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Algorithm
{
public class Expression
{
public string BuildRandom(int operatorCount)
{
BinTree<ExpressionItem> actual;
actual = BuildRandomBinTree(operatorCount);
string re = Merge(actual);
return re;
}
/// <summary>
///
/// </summary>
/// <param name="operandCount"></param>
/// <returns></returns>
public BinTree<ExpressionItem> BuildRandomBinTree(int opCount)
{
BinTree<ExpressionItem> tree = new BinTree<ExpressionItem>();
Queue<BinTreeNode<ExpressionItem>> que = new Queue<BinTreeNode<ExpressionItem>>();
Random ValueRand = new Random();
tree.Root = new BinTreeNode<ExpressionItem>();
tree.Root.Value = GetRandOperatorItem(ValueRand);
que.Enqueue(tree.Root);
int preCount = que.Count;
int k = 1;
while (k < opCount || que.Count > 0)
{
BinTreeNode<ExpressionItem> parent = que.Dequeue();
if (parent.Value.CombineType == OperatorCombineType.Two)
{
//left
ExpressionItem leftItem;
if (k < opCount)
{
leftItem = GetRandOperatorItem(ValueRand);
}
else
{
leftItem = GetRandOperandItem(ValueRand);
}
BinTreeNode<ExpressionItem> leftNode = new BinTreeNode<ExpressionItem>();
leftNode.Value = leftItem;
parent.LeftChild = leftNode;
que.Enqueue(leftNode);
k++;
ExpressionItem rightItem;
if (k < opCount)
{
rightItem = GetRandOperatorItem(ValueRand);
}
else
{
rightItem = GetRandOperandItem(ValueRand);
}
BinTreeNode<ExpressionItem> rightNode = new BinTreeNode<ExpressionItem>();
rightNode.Value = rightItem;
parent.RightChild = rightNode;
que.Enqueue(rightNode);
k++;
//right
}
else if (parent.Value.CombineType == OperatorCombineType.One)
{
ExpressionItem leftItem;
if (k < opCount)
{
leftItem = GetRandOperatorItem(ValueRand);
}
else
{
leftItem = GetRandOperandItem(ValueRand);
}
BinTreeNode<ExpressionItem> leftNode = new BinTreeNode<ExpressionItem>();
leftNode.Value = leftItem;
parent.LeftChild = leftNode;
que.Enqueue(leftNode);
k++;
}
}
return tree;
}
/// <summary>
///
/// </summary>
/// <param name="ValueRand"></param>
/// <param name="possibility">1-100.default:50</param>
/// <returns></returns>
private static bool RandomHas(Random ValueRand, Int16 possibility = 50)
{
bool hasNode = (Int32)(ValueRand.NextDouble() * 100) < possibility;
return hasNode;
}
private ExpressionItem GetRandOperandItem(Random ValueRand)
{
ExpressionItem item = new ExpressionItem();
item.Value = (ValueRand.NextDouble() * 1000).ToString("#####.##");
item.CellType = ExpressionCellType.Operand;
return item;
}
private ExpressionItem GetRandOperatorItem(Random ValueRand)
{
ExpressionItem item = new ExpressionItem();
string operators = "++--**//%";
int index = ValueRand.Next(0, operators.Length);
item.Value = operators[index].ToString();
item.CellType = ExpressionCellType.Operator;
item.CombineType = OperatorCombineType.Two;
if (item.Value == "-")
{
bool two = RandomHas(ValueRand, 60);
if (!two)
{
item.CombineType = OperatorCombineType.One;
}
}
return item;
}
private ExpressionItem GetRandItem(Random ValueRand)
{
bool isOperand = RandomHas(ValueRand);
if (isOperand)
{
return GetRandOperandItem(ValueRand);
}
else
{
return GetRandOperatorItem(ValueRand);
}
}
public string Merge(BinTree<ExpressionItem> tree)
{
string result = MergeInternal(tree.Root);
return result;
}
public static Int32 GetPriority(ExpressionItem item)
{
Int32 priority = -1;
if (item.CombineType == OperatorCombineType.One)
{
priority += 100;
}
else if (item.CombineType == OperatorCombineType.Two)
{
if ("+-".IndexOf(item.Value) > -1)
{
priority += 5;
}
else if ("*/%".IndexOf(item.Value) > -1)
{
priority += 10;
}
}
if (item.WrappedBracket)
{
priority = Int32.MaxValue;
}
return priority;
}
public string MergeInternal(BinTreeNode<ExpressionItem> root)
{
if (root == null)
{
return string.Empty;
}
else if (root.LeftChild == null && root.RightChild == null)
{
return root.Value.Value;
}
else
{
string left = MergeInternal(root.LeftChild);
string right = MergeInternal(root.RightChild);
string result = string.Empty;
if (root.Value.CombineType == OperatorCombineType.Two)
{
if (root.LeftChild.Value.CellType == ExpressionCellType.Operator)
{
if (GetPriority(root.LeftChild.Value) < GetPriority(root.Value)
&&!root.LeftChild.Value.WrappedBracket
)
{
left = "(" + left + ")";
root.LeftChild.Value.WrappedBracket = true;
}
}
if (root.RightChild.Value.CellType == ExpressionCellType.Operator)
{
if (GetPriority(root.RightChild.Value) < GetPriority(root.Value)
&& !root.RightChild.Value.WrappedBracket
)
{
right = "(" + left + ")";
root.RightChild.Value.WrappedBracket = true;
}
}
result = left + root.Value.Value + right;
}
else if (root.Value.CombineType == OperatorCombineType.One)
{
if (root.LeftChild.Value.CellType == ExpressionCellType.Operator)
{
if (GetPriority(root.LeftChild.Value) <= GetPriority(root.Value)
&& !root.LeftChild.Value.WrappedBracket
)
{
left = "(" + left + ")";
root.LeftChild.Value.WrappedBracket = true;
}
}
result = root.Value.Value + left;
}
return result;
}
}
}
}
浙公网安备 33010602011771号