zoukankan      html  css  js  c++  java
  • C# 版本的24点实现

    C# 版本的24点实现。

    已经实现基本功能,可以正确的算 3, 3, 8, 8 这类组合。
    稍加修改就可以支持任意数目的操作数和操作符组合形成的四则运算表达式,不限于24点。

    代码还比较简单粗糙,晚一点优化了再更新此贴。

    关于二叉树拓扑结构的遍历,参考了:

    http://blogs.msdn.com/b/ericlippert/archive/2010/04/19/every-binary-tree-there-is.aspx

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace calc24
    {
    	class MainClass
    	{
    		public static void Main (string[] args)
    		{
    			var permuteOfNums = Permute (new List<int> { 4, 5, 6, 7 });
    
    			foreach (var op1 in new List<string>{"+","-","*","/"}) {
    				foreach (var op2 in new List<string>{"+","-","*","/"}) {
    					foreach (var op3 in new List<string>{"+","-","*","/"}) {
    						var ops = new List<string>{ op1, op2, op3 };
    
    						foreach (var node in AllCompleteBinaryTreesOf7Nodes()) {
    							foreach (var nums in permuteOfNums) {
    								var tree = CreateOne24CalculationFormula (node, nums, ops);
    								try {
    									var result = Evaluate (tree);
    
    									if (Math.Abs (result - 24) < 0.0001) {
    										Console.WriteLine (BinaryTreeString (tree));
    									}
    								} catch (DivideByZeroException) {
    
    								}
    							}
    						}
    					}
    				}
    			}
    		}
    
    		static float Evaluate (Node node)
    		{
    			switch (node.Data) {
    			case "+":
    				return Evaluate (node.Left) + Evaluate (node.Right);
    			case "-":
    				return Evaluate (node.Left) - Evaluate (node.Right);
    			case "*":
    				return Evaluate (node.Left) * Evaluate (node.Right);
    			case "/":
    				return Evaluate (node.Left) / Evaluate (node.Right);
    			default:
    				return float.Parse (node.Data);
    			}
    		}
    
    		static Node CreateOne24CalculationFormula (Node node, List<int> nums, List<string> operators)
    		{
    
    			Node result = null;
    			var iNums = 0;
    			var iOps = 0;
    
    			Func<Node, Node> copy = null;
    
    			copy = (src) => {
    				Node dest;
    
    				if (src.Left == null && src.Right == null) {
    					dest = new Node (null, null, nums [iNums++].ToString ());
    				} else {
    					var left = copy (src.Left);
    					var right = copy (src.Right);
    
    					dest = new Node (left, right, operators [iOps++]);
    				}
    
    				return dest;
    			};
    
    			result = copy (node);
    
    			return result;
    		}
    
    		static IEnumerable<List<T>> Permute<T> (List<T> elements)
    		{
    			if (elements.Count == 1)
    				return EnumerableOfOneElement (elements);
    
    			IEnumerable<List<T>> result = null;
    
    			foreach (var first in elements) {
    				var remaining = elements.ToArray ().ToList ();
    				remaining.Remove (first);
    
    				var permutesOfRemaining = Permute (remaining);
    
    				foreach (var p in permutesOfRemaining) {
    					var arr = new List<T> { first };
    					arr.AddRange (p);
    
    					var seq = EnumerableOfOneElement (arr);
    
    					if (result == null) {
    						result = seq;
    					} else {
    						result = Enumerable.Union (result, seq);
    					}
    				}
    			}
    
    			return result;
    		}
    
    		static IEnumerable<T> EnumerableOfOneElement<T> (T element)
    		{
    			yield return element;
    		}
    
    		static IEnumerable<Node> AllCompleteBinaryTreesOf7Nodes ()
    		{
    			var trees = AllBinaryTrees (7);
    			return (from t in trees
    			        where IsCompleteBinaryTree (t)
    			        select t);
    		}
    
    		static bool IsCompleteBinaryTree (Node node)
    		{
    			if (node == null)
    				return true;
    
    			if (node.Left == null && node.Right != null ||
    			    node.Left != null && node.Right == null)
    				return false;
    
    			return IsCompleteBinaryTree (node.Left) && IsCompleteBinaryTree (node.Right);
    		}
    
    		static IEnumerable<Node> AllBinaryTrees (int size)
    		{
    			if (size == 0)
    				return new Node[] { null };
    			return from i in Enumerable.Range (0, size)
    			       from left in AllBinaryTrees (i)
    			       from right in AllBinaryTrees (size - 1 - i)
    			       select new Node (left, right, "");
    		}
    
    		public static string BinaryTreeString (Node node)
    		{
    			var sb = new StringBuilder ();
    			Action<Node> f = null;
    			f = n => {
    				if (n == null) {
    					//sb.Append ("x");
    				} else if (new []{ "+", "-", "*", "/" }.Contains (n.Data)) {
    
    					sb.Append ("(");
    					f (n.Left);
    
    					sb.Append (" " + n.Data + " ");
    
    					f (n.Right);
    					sb.Append (")");
    
    				} else {
    					sb.Append (n.Data);
    				}
    			};
    			f (node);
    			return sb.ToString ();
    		}
    	}
    
    	class Node
    	{
    		public Node Left { get; set; }
    
    		public Node Right { get; set; }
    
    		public string Data { get; set; }
    
    		public Node ()
    		{
    
    		}
    
    		public Node (Node left, Node right, string data)
    		{
    			this.Left = left;
    			this.Right = right;
    			this.Data = data;
    		}
    	}
    }
    

    测试:

    (4 * ((5 + 7) - 6))
    (4 * ((7 + 5) - 6))
    ((5 + 7) * (6 - 4))
    ((7 + 5) * (6 - 4))
    (((5 + 7) - 6) * 4)
    (((7 + 5) - 6) * 4)
    (4 * (5 + (7 - 6)))
    (4 * (7 + (5 - 6)))
    (4 * ((5 - 6) + 7))
    (4 * ((7 - 6) + 5))
    ((6 - 4) * (5 + 7))
    ((6 - 4) * (7 + 5))
    ((5 + (7 - 6)) * 4)
    ((7 + (5 - 6)) * 4)
    (((5 - 6) + 7) * 4)
    (((7 - 6) + 5) * 4)
    (4 * (5 - (6 - 7)))
    (4 * (7 - (6 - 5)))
    ((5 - (6 - 7)) * 4)
    ((7 - (6 - 5)) * 4)
    
    Press any key to continue...
  • 相关阅读:
    Java High Level REST Client 中文API(仅供参考)
    3.2_springBoot2.1.x检索之JestClient操作ElasticSearch
    3.1_springboot2.x检索之elasticsearch安装&快速入门
    2.2_springboot2.x消息RabbitMQ整合&amqpAdmin管理组件的使用
    2.1_springboot2.x消息介绍&RabbitMQ运行机制
    1.2_springboot2.x中redis缓存&原理介绍
    1.1_springboot2.x与缓存原理介绍&使用缓存
    JavaWeb-----Get请求和Post请求
    Java基础(basis)-----TCP通信
    Java基础(basis)-----泛型详解
  • 原文地址:https://www.cnblogs.com/thomas888/p/csharp-calc24.html
Copyright © 2011-2022 走看看