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. 048 hive运行的相关配置

    一:执行SQL的方式 1.配置的键值 2.minimal下运行fetch 3.设定hive.fetch.task.conversion=more 4.在more下运行fetch 二:虚拟列 一共三个虚 ...

  2. docker 部署springboot应用

    第一步:搭建springboot的web应用,可在CMD命令行中通过mvn install命令将应用打成jar包:如demo-0.0.1-SNAPSHOT.jar 第二步:将jar包copy到cent ...

  3. codeforces-1111

    https://www.cnblogs.com/31415926535x/p/10397007.html codeforces 537 div2 A 题意就是给你两个字符串,然后如果s,t的对应位上的 ...

  4. [洛谷P2066]机器分配

    题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M≤15,N≤10.分 ...

  5. GCC&&GDB在OI中的介绍

    序言 这本来是用Word写的,但是后来我换了系统所以只能用markdown迁移然后写了...... $\qquad$本文主要投食给那些在Windows下活了很久然后考试时发现需要用命令行来操作时困惑万 ...

  6. Python3面向对象基础

    面向对象概述 面向对象 面向对象的世界,引入了对象的概念,对象具有属性:数据,对象具有过程或者方法:成员函数.成员函数的作用就是处理属性. 例子 对象:Car 属性:fuel_level, isSed ...

  7. 潭州课堂25班:Ph201805201 爬虫基础 第十二课 点触验证码二 (课堂笔记)

    为上次代码添加 模拟人操作 的鼠标的移动轨迹 # -*- coding:utf-8 -*- # 斌彬电脑 # @Time : 2018/9/14 0014 上午 8:08 from selenium ...

  8. [POI2011]Rotacje na drzewie (2)/[BZOJ3702]二叉树

    [POI2011]Rotacje na drzewie (2) 题目大意: 一棵有\(n\)个叶子结点的二叉树,每个叶子结点有一个权值,恰好是\(1\sim n\)的一个排列,你可以任意交换每一对子结 ...

  9. 一款功能强悍的web磁盘管理工具 (A powerful web disk management tools)

    https://github.com/kingAnyWHere/web-ftp web-ftp 一款功能强悍的web磁盘管理工具 (A powerful web disk management too ...

  10. centos 7 安装 php 5.5 5.6 7.0

    查看当前安装的PHP包 [root@node1 ~]# yum list installed | grep php php56w.x86_64 -.w7 @webtatic php56w-cli.x8 ...