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. Educational Codeforces Round 26 E - Vasya's Function

    数论题还是好恶心啊. 题目大意:给你两个不超过1e12的数 x,y,定义一个f ( x, y ) 如果y==0 返回 0 否则返回1+ f ( x , y - gcd( x , y ) ); 思路:我 ...

  2. 【Java】 剑指offer(7) 二叉树的下一个结点

    本文参考自<剑指offer>一书,代码采用Java语言.  更多:<剑指Offer>Java实现合集 题目 给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?  ...

  3. 2019最新最全HUSTOJ本地及云端服务器搭建(基于腾讯云服务器)

    在刚接触ACM的时候,对于那些在线测评的网站很感兴趣,就在网上搜索了一下,在Github上发现了一个有趣的项目,然后在 Github 上获取 了HUST OJ 的开源项目代码,根据网上的教程踩了无数的 ...

  4. Windows 下安装 swoole 具体步骤(php)

    Windows 下安装 swoole 具体步骤: Swoole,原本不支持在Windows下安装的,所以我们要安装Cygwin来使用.在安装Cygwin下遇到了很多坑,百度经验上的文档不是很全,所以我 ...

  5. 一款易搭建,运行快的Git服务器:Gitea安装教程

    说明:Gitea是从Gogs发展而来,同样的拥有极易安装,运行快速的特点,而且更新比Gogs频繁很多,维护的人也多,个人认为Gitea还是更好一些的,这里就说下安装方法. 截图 简介 Gitea是一个 ...

  6. JavaScript简易教程

    这是我所知道的最完整最简洁的JavaScript基础教程. 这篇文章带你尽快走进JavaScript的世界——前提是你有一些编程经验的话.本文试图描述这门语言的最小子集.我给这个子集起名叫做“Java ...

  7. mysql安装后不是内部或外部命令解决

    在环境变量中配置mysql的bin 怎么找到bin目录,在管理工具,服务,常规选项卡下找到 双击mysql后,常规选项卡下的路径就是bin的路径,然后把该路径配置到环境变量中,即可,然后net sta ...

  8. AFN和GCD并行同步问题

    链接: GCD 中组队列group与Afnetworking的结合使用 使用AFNetworking3.0实现接口异步并发 从并发编程到GCD浅述之一----任务.队列.线程复用.AFN3.0同步请求 ...

  9. iOS11适配

    链接: 你可能需要为你的 APP 适配 iOS 11 iOS11新特性,如何适配iOS11 App界面适配iOS11(包括iPhoneX的奇葩尺寸) iOS 11 安全区域适配总结 iOS 11 sa ...

  10. MVVM设计模式和在WPF中的实现(四) 事件绑定

    系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中的实现(三)命令绑定 MVVM模式解析和在WPF中的 ...