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...

C# 版本的24点实现的更多相关文章

  1. Racket 版本的 24 点实现

    Racket 版本的 24 点实现 #lang racket ; Author: woodfox ; Date: Oct 11, 2014 ; ==================== 1. Non- ...

  2. 团队作业4--第一次项目冲刺(Alpha版本)预备工作

    小组说明 我们组是从周一开始对项目进行研究讨论并编程的,因为我们看截止日期是周日,就从周一才开始,起步晚了,是我们认识上的失误,导致我们周一周二的步伐没有协调好,项目进展的不稳定,但是我们在上周末并不 ...

  3. ESP-IDF版本2.1.1

    版本2.1.1是一个错误修复版本.它包括对KRACK和BlueBorne漏洞的修复. 版本2.1.1的文档可在http://esp-idf.readthedocs.io/en/v2.1.1/上找到. ...

  4. Android 7.0以上版本 系统解决拍照的问题 exposed beyond app through ClipData.Item.getUri()

    解决方案1: android.os.FileUriExposedException: file:///storage/emulated/0/ilive/images/photophoto.jpeg e ...

  5. 交叉编译OpenCV的Android版本

    交叉编译OpenCV的Android版本 OpenCV作为一个强大的图像处理库,在Android上也有强大的应用. OpenCV官网提供了SDK的下载,可以直接下载使用 OpenCV官网地址:http ...

  6. selenium:chromedriver与chrome版本的对应关系

    转自:http://blog.csdn.NET/huilan_same/article/details/51896672 再使用selenium打开chrome浏览器的时候,需要用chromedriv ...

  7. 四、10分钟ToPandas_0.24.2

    # Author:Zhang Yuan整理,版本Pandas0.24.2 # 0. 习惯上,我们会按下面格式引入所需要的包: import pandas as pd import numpy as n ...

  8. OpenCV.3.4.6_VS2015&cmake编译x86版本的bin&lib

    ZC:<<OpenCV3编程入门>> 的 2.2.2 中也有该内容的讲解 1.参考网址:opencv3.3.0+vs2015+cmake编译opencv x86 - wowo的 ...

  9. PDF 文件编写器 C# 类库(版本 1.28.0)使用详解

    PDF File Writer 是一个 C# .NET 类库,允许应用程序创建 PDF 文件. PDF File Writer C# 类库使 .NET 应用程序能够生成 PDF 文档.该库使应用程序免 ...

随机推荐

  1. Camera摄像头

    <LinearLayout android:id="@+id/btn_layout" android:layout_width="match_parent" ...

  2. 【知了堂学习笔记】java 自定义异常

    java 常见异常种类(Java Exception): 算术异常类:ArithmeticExecption 空指针异常类:NullPointerException 类型强制转换异常:ClassCas ...

  3. GreenDao与ReactiveX的完美搭配

    转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6719380.html 作为Android开发者,一定不会对 GreenDao 和 ReactiveX 陌生 ...

  4. TXT 与 DataTable 互转

    //********************************************************************************************* publ ...

  5. mvc返回多个结果集,返回多个视图

    System.Web.Mvc.ViewPage<dynamic> public ActionResult Index()     {             IDictionary< ...

  6. iOS html5使用缓存并及时更新方案总结

    最近一段时间研究了一下H5在iOS移动端表现时使用缓存并可及时更新方案,总结如下: 一.使用Webview自带缓存机制 当我们使用webview加载html资源时的,本质上就是一个向服务器索取资源的h ...

  7. CAD画图技巧经验

    1.CAD中如何输入特殊符号 %% d ——绘制“℃”符号.例如: 98.6 ℃—— 98.6 %% dC : %% c ——绘制圆直径“φ”符号.例如:φ 30 ——%% c30 : %% p —— ...

  8. [NOIp2013普及组]车站分级

    思路: 对于每一趟车,将区间内所有经停的站和所有未经停的站连一条边,表示前者优先级一定高于后者,然后用Kahn跑一遍拓扑排序即可.然而这样会创造大量多余的边,会TLE1个点.考虑一种优化:因为每趟车本 ...

  9. NOIP 2006 作业调度方案

    [问题描述] 我们现在要利用m台机器加工n个工件,每个工件都有m道工序,每道工序都在不同的指定的机器上完成.每个工件的每道工序都有指定的加工时间. 每个工件的每个工序称为一个操作,我们用记号j-k表示 ...

  10. W3School 学习笔记

    网站构建初级教程 1.每个网站开发人员都有必要了解以下几方面的知识: 万维网如何工作 HTML 语言 如何使用层叠样式表 (CSS) JavaScript 编程 XML 标准 服务器脚本技术 使用 S ...