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;

            }

        }


    }
}

posted on 2011-07-29 17:31  netfuns  阅读(291)  评论(0)    收藏  举报