最近做了一个24点的程序,思想是循环生成4个数的排列和11种表达式,再计算结果,如果为24则成功。
注:生成的数使用扑克牌显示。
一些关键的类如下:
1.排列组合类
2.表达式计算类
3.24点计算类
软件截图:
对应的源代码如下:
1.排列组合类:
//-----------------------------------------------------------------------------
//
// 算法:排列组合类
//
// 版权所有(C) Snowdust
// 个人博客 http://blog.csdn.net/snowdust & http://snowdust.cnblogs.com
// MSN & Email snowdust77@sina.com
//
// 此源代码可免费用于各类软件(含商业软件)
// 允许对此代码的进一步修改与开发
// 但必须完整保留此版权信息
//
// 调用方法如下:
//
// 1.GetPermutation(T[], startIndex, endIndex)
// 对startIndex到endIndex进行排列,其余元素不变
//
// 2.GetPermutation(T[])
// 返回数组所有元素的全排列
//
// 3.GetPermutation(T[], n)
// 返回数组中n个元素的排列
//
// 4.GetCombination(T[], n)
// 返回数组中n个元素的组合
//
// 版本历史:
// V0.1 2010-01-20 摘要:首次创建
//
//-----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
namespace Arithmetic
{
public class PermutationAndCombination<T>
{
#region 内部方法
/// <summary>
/// 递归算法求数组的组合(私有成员)
/// </summary>
/// <param name="list">返回的范型</param>
/// <param name="t">所求数组</param>
/// <param name="n">辅助变量</param>
/// <param name="m">辅助变量</param>
/// <param name="b">辅助数组</param>
/// <param name="M">辅助变量M</param>
private static void GetCombination(ref List<T[]> list, T[] t, int n, int m, int[] b, int M)
{
for (int i = n; i >= m; i--)
{
b[m - 1] = i - 1;
if (m > 1)
{
GetCombination(ref list, t, i - 1, m - 1, b, M);
}
else
{
if (list == null)
{
list = new List<T[]>();
}
T[] temp = new T[M];
for (int j = 0; j < b.Length; j++)
{
temp[j] = t[b[j]];
}
list.Add(temp);
}
}
}
/// <summary>
/// 递归算法求排列(私有成员)
/// </summary>
/// <param name="list">返回的列表</param>
/// <param name="t">所求数组</param>
/// <param name="startIndex">起始标号</param>
/// <param name="endIndex">结束标号</param>
private static void GetPermutation(ref List<T[]> list, T[] t, int startIndex, int endIndex)
{
if (startIndex == endIndex)
{
if (list == null)
{
list = new List<T[]>();
}
T[] temp = new T[t.Length];
t.CopyTo(temp, 0);
list.Add(temp);
}
else
{
for (int i = startIndex; i <= endIndex; i++)
{
Swap(ref t[startIndex], ref t[i]);
GetPermutation(ref list, t, startIndex + 1, endIndex);
Swap(ref t[startIndex], ref t[i]);
}
}
}
#endregion
#region 公共方法
/// <summary>
/// 交换两个变量
/// </summary>
/// <param name="a">变量1</param>
/// <param name="b">变量2</param>
public static void Swap(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
/// <summary>
/// 求从起始标号到结束标号的排列,其余元素不变
/// </summary>
/// <param name="t">所求数组</param>
/// <param name="startIndex">起始标号</param>
/// <param name="endIndex">结束标号</param>
/// <returns>从起始标号到结束标号排列的范型</returns>
public static List<T[]> GetPermutation(T[] t, int startIndex, int endIndex)
{
if (startIndex < 0 || endIndex > t.Length - 1)
{
return null;
}
List<T[]> list = new List<T[]>();
GetPermutation(ref list, t, startIndex, endIndex);
return list;
}
/// <summary>
/// 返回数组所有元素的全排列
/// </summary>
/// <param name="t">所求数组</param>
/// <returns>全排列的范型</returns>
public static List<T[]> GetPermutation(T[] t)
{
return GetPermutation(t, 0, t.Length - 1);
}
/// <summary>
/// 求数组中n个元素的排列
/// </summary>
/// <param name="t">所求数组</param>
/// <param name="n">元素个数</param>
/// <returns>数组中n个元素的排列</returns>
public static List<T[]> GetPermutation(T[] t, int n)
{
if (n > t.Length)
{
return null;
}
List<T[]> list = new List<T[]>();
List<T[]> c = GetCombination(t, n);
for (int i = 0; i < c.Count; i++)
{
List<T[]> l = new List<T[]>();
GetPermutation(ref l, c[i], 0, n - 1);
list.AddRange(l);
}
return list;
}
/// <summary>
/// 求数组中n个元素的组合
/// </summary>
/// <param name="t">所求数组</param>
/// <param name="n">元素个数</param>
/// <returns>数组中n个元素的组合的范型</returns>
public static List<T[]> GetCombination(T[] t, int n)
{
if (t.Length < n)
{
return null;
}
int[] temp = new int[n];
List<T[]> list = new List<T[]>();
GetCombination(ref list, t, t.Length, n, temp, n);
return list;
}
#endregion
}
}
//
// 算法:排列组合类
//
// 版权所有(C) Snowdust
// 个人博客 http://blog.csdn.net/snowdust & http://snowdust.cnblogs.com
// MSN & Email snowdust77@sina.com
//
// 此源代码可免费用于各类软件(含商业软件)
// 允许对此代码的进一步修改与开发
// 但必须完整保留此版权信息
//
// 调用方法如下:
//
// 1.GetPermutation(T[], startIndex, endIndex)
// 对startIndex到endIndex进行排列,其余元素不变
//
// 2.GetPermutation(T[])
// 返回数组所有元素的全排列
//
// 3.GetPermutation(T[], n)
// 返回数组中n个元素的排列
//
// 4.GetCombination(T[], n)
// 返回数组中n个元素的组合
//
// 版本历史:
// V0.1 2010-01-20 摘要:首次创建
//
//-----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
namespace Arithmetic
{
public class PermutationAndCombination<T>
{
#region 内部方法
/// <summary>
/// 递归算法求数组的组合(私有成员)
/// </summary>
/// <param name="list">返回的范型</param>
/// <param name="t">所求数组</param>
/// <param name="n">辅助变量</param>
/// <param name="m">辅助变量</param>
/// <param name="b">辅助数组</param>
/// <param name="M">辅助变量M</param>
private static void GetCombination(ref List<T[]> list, T[] t, int n, int m, int[] b, int M)
{
for (int i = n; i >= m; i--)
{
b[m - 1] = i - 1;
if (m > 1)
{
GetCombination(ref list, t, i - 1, m - 1, b, M);
}
else
{
if (list == null)
{
list = new List<T[]>();
}
T[] temp = new T[M];
for (int j = 0; j < b.Length; j++)
{
temp[j] = t[b[j]];
}
list.Add(temp);
}
}
}
/// <summary>
/// 递归算法求排列(私有成员)
/// </summary>
/// <param name="list">返回的列表</param>
/// <param name="t">所求数组</param>
/// <param name="startIndex">起始标号</param>
/// <param name="endIndex">结束标号</param>
private static void GetPermutation(ref List<T[]> list, T[] t, int startIndex, int endIndex)
{
if (startIndex == endIndex)
{
if (list == null)
{
list = new List<T[]>();
}
T[] temp = new T[t.Length];
t.CopyTo(temp, 0);
list.Add(temp);
}
else
{
for (int i = startIndex; i <= endIndex; i++)
{
Swap(ref t[startIndex], ref t[i]);
GetPermutation(ref list, t, startIndex + 1, endIndex);
Swap(ref t[startIndex], ref t[i]);
}
}
}
#endregion
#region 公共方法
/// <summary>
/// 交换两个变量
/// </summary>
/// <param name="a">变量1</param>
/// <param name="b">变量2</param>
public static void Swap(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
/// <summary>
/// 求从起始标号到结束标号的排列,其余元素不变
/// </summary>
/// <param name="t">所求数组</param>
/// <param name="startIndex">起始标号</param>
/// <param name="endIndex">结束标号</param>
/// <returns>从起始标号到结束标号排列的范型</returns>
public static List<T[]> GetPermutation(T[] t, int startIndex, int endIndex)
{
if (startIndex < 0 || endIndex > t.Length - 1)
{
return null;
}
List<T[]> list = new List<T[]>();
GetPermutation(ref list, t, startIndex, endIndex);
return list;
}
/// <summary>
/// 返回数组所有元素的全排列
/// </summary>
/// <param name="t">所求数组</param>
/// <returns>全排列的范型</returns>
public static List<T[]> GetPermutation(T[] t)
{
return GetPermutation(t, 0, t.Length - 1);
}
/// <summary>
/// 求数组中n个元素的排列
/// </summary>
/// <param name="t">所求数组</param>
/// <param name="n">元素个数</param>
/// <returns>数组中n个元素的排列</returns>
public static List<T[]> GetPermutation(T[] t, int n)
{
if (n > t.Length)
{
return null;
}
List<T[]> list = new List<T[]>();
List<T[]> c = GetCombination(t, n);
for (int i = 0; i < c.Count; i++)
{
List<T[]> l = new List<T[]>();
GetPermutation(ref l, c[i], 0, n - 1);
list.AddRange(l);
}
return list;
}
/// <summary>
/// 求数组中n个元素的组合
/// </summary>
/// <param name="t">所求数组</param>
/// <param name="n">元素个数</param>
/// <returns>数组中n个元素的组合的范型</returns>
public static List<T[]> GetCombination(T[] t, int n)
{
if (t.Length < n)
{
return null;
}
int[] temp = new int[n];
List<T[]> list = new List<T[]>();
GetCombination(ref list, t, t.Length, n, temp, n);
return list;
}
#endregion
}
}
2.表达式计算类
//-----------------------------------------------------------------------------
//
// 算法:表达式计算类
//
// 版权所有(C) Snowdust
// 个人博客 http://blog.csdn.net/snwodust & http://snowdust.cnblogs.com
// MSN & Email snwodust77@sina.com
//
// 此源代码可免费用于各类软件(含商业软件)
// 允许对此代码的进一步修改与开发
// 但必须完整保留此版权信息
//
// 支持以下运算符:加(+)、减(-)、乘(*)、除(/)和幂(^)
//
// 如果表达式错误,将返回null值
//
// 调用方法如下:
//
// Calculate(expression)
// 返回double?类型的值
// 例如 Calculate("3+4*(5-2)^2+4") = 43
//
// 版本历史:
// V0.1 2010-01-20 摘要:首次创建
//
//-----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
namespace Arithmetic
{
public class Calculator
{
#region 定义变量
/// <summary>
/// 运算符左优先级
/// </summary>
private static Dictionary<char, int> m_LeftPriority = new Dictionary<char, int>();
/// <summary>
/// 运算符右优先级
/// </summary>
private static Dictionary<char, int> m_RightPriority = new Dictionary<char, int>();
/// <summary>
/// 栈
/// </summary>
private static Stack<double> m_Stack = new Stack<double>();
#endregion
#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
static Calculator()
{
if (m_LeftPriority.Count == 0)
{
m_LeftPriority.Add('=', 0);
m_LeftPriority.Add('(', 10);
m_LeftPriority.Add('*', 50);
m_LeftPriority.Add('/', 50);
m_LeftPriority.Add('^', 70);
m_LeftPriority.Add('+', 30);
m_LeftPriority.Add('-', 30);
m_LeftPriority.Add(')', 80);
}
if (m_RightPriority.Count == 0)
{
m_RightPriority.Add('=', 0);
m_RightPriority.Add('(', 80);
m_RightPriority.Add('*', 40);
m_RightPriority.Add('/', 40);
m_RightPriority.Add('^', 60);
m_RightPriority.Add('+', 20);
m_RightPriority.Add('-', 20);
m_RightPriority.Add(')', 10);
}
}
#endregion
#region 内部方法
/// <summary>
/// 判断字符是否为运算符
/// </summary>
/// <param name="ch">待判断的字符</param>
/// <returns>如果是运算符,返回True,否则返回False</returns>
private static bool IsOperator(char ch)
{
if (ch == '(' || ch == ')' || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^')
{
return true;
}
return false;
}
/// <summary>
/// 判断运算符的优先级
/// </summary>
/// <param name="op1">第1个运算符</param>
/// <param name="op2">第2个运算符</param>
/// <returns>优先级:op1大于op2,返回1,op1等于op2-返回0,op1小于op2,返回-1</returns>
private static int Precede(char op1, char op2)
{
return m_LeftPriority[op1].CompareTo(m_RightPriority[op2]);
}
/// <summary>
/// 操作数进栈
/// </summary>
/// <param name="operand"></param>
private static void PushOperand(double operand)
{
m_Stack.Push(operand);
}
/// <summary>
/// 获取栈中最近的两个操作数
/// </summary>
/// <param name="operand1">第1个操作数</param>
/// <param name="operand2">第2个操作数</param>
private static bool GetTwoOperands(ref double operand1, ref double operand2)
{
bool ret = true;
if (m_Stack.Count == 0)
{
// 表达式有误
m_Stack.Clear();
ret = false;
}
operand1 = m_Stack.Pop();
if (m_Stack.Count == 0)
{
// 表达式有误
m_Stack.Clear();
ret = false;
}
operand2 = m_Stack.Pop();
return ret;
}
/// <summary>
/// 计算一次结果
/// </summary>
/// <param name="op">操作符</param>
private static bool Calculate(char op)
{
double operand1 = 0, operand2 = 0, result = 0;
bool ret = GetTwoOperands(ref operand1, ref operand2);
if (!ret)
{
ret = false;
return ret;
}
switch (op)
{
case '+': result = operand2 + operand1; break;
case '-': result = operand2 - operand1; break;
case '*': result = operand2 * operand1; break;
case '^': result = System.Math.Pow(operand2, operand1); break;
case '/':
if (operand1 == 0)
{
// 被0除
m_Stack.Clear();
ret = false;
}
else
{
result = operand2 / operand1;
}
break;
}
m_Stack.Push(result);
return ret;
}
#endregion
#region 公共方法
/// <summary>
/// 将中缀表达式转换成后缀表达式
/// </summary>
/// <param name="expression">中缀表达式</param>
/// <returns>后缀表达式</returns>
public static string TransExpression(string expression)
{
Stack<char> s = new Stack<char>();
s.Push('=');
int index = 0;
string ret = string.Empty;
while (index < expression.Length)
{
char ch = expression[index];
if (!IsOperator(ch))
{
while (index < expression.Length && expression[index] >= '0' && expression[index] <= '9')
{
ret += expression[index];
index++;
}
ret += '#';
}
else
{
switch (Precede(s.Peek(), ch))
{
case -1:
s.Push(ch);
index++;
break;
case 0:
s.Pop();
index++;
break;
case 1:
ret += s.Pop();
break;
}
}
}
while (s.Peek() != '=')
{
ret += s.Pop();
}
return ret;
}
/// <summary>
/// 计算表达式的值(无需带=号)
/// </summary>
/// <param name="expression">待计算的表达式</param>
/// <returns>表达式的值</returns>
public static double? Calculate(string expression)
{
double operand;
m_Stack.Clear();
string exp = TransExpression(expression);
exp += ' ';
int index = 0;
char ch = exp[index];
try
{
while (ch != ' ')
{
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^')
{
bool ret = Calculate(ch);
if (!ret)
{
return null;
}
index++;
ch = exp[index];
}
else if (ch == '#')
{
index++;
ch = exp[index];
}
else
{
operand = 0;
while (ch >= '0' && ch <= '9')
{
operand = operand * 10 + Convert.ToDouble(ch.ToString());
index++;
ch = exp[index];
}
m_Stack.Push(operand);
}
}
if (m_Stack.Count == 0)
{
// 表达式有误
return null;
}
double d = m_Stack.Pop();
m_Stack.Clear();
return d;
}
catch
{
return null;
}
}
#endregion
}
}
//
// 算法:表达式计算类
//
// 版权所有(C) Snowdust
// 个人博客 http://blog.csdn.net/snwodust & http://snowdust.cnblogs.com
// MSN & Email snwodust77@sina.com
//
// 此源代码可免费用于各类软件(含商业软件)
// 允许对此代码的进一步修改与开发
// 但必须完整保留此版权信息
//
// 支持以下运算符:加(+)、减(-)、乘(*)、除(/)和幂(^)
//
// 如果表达式错误,将返回null值
//
// 调用方法如下:
//
// Calculate(expression)
// 返回double?类型的值
// 例如 Calculate("3+4*(5-2)^2+4") = 43
//
// 版本历史:
// V0.1 2010-01-20 摘要:首次创建
//
//-----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
namespace Arithmetic
{
public class Calculator
{
#region 定义变量
/// <summary>
/// 运算符左优先级
/// </summary>
private static Dictionary<char, int> m_LeftPriority = new Dictionary<char, int>();
/// <summary>
/// 运算符右优先级
/// </summary>
private static Dictionary<char, int> m_RightPriority = new Dictionary<char, int>();
/// <summary>
/// 栈
/// </summary>
private static Stack<double> m_Stack = new Stack<double>();
#endregion
#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
static Calculator()
{
if (m_LeftPriority.Count == 0)
{
m_LeftPriority.Add('=', 0);
m_LeftPriority.Add('(', 10);
m_LeftPriority.Add('*', 50);
m_LeftPriority.Add('/', 50);
m_LeftPriority.Add('^', 70);
m_LeftPriority.Add('+', 30);
m_LeftPriority.Add('-', 30);
m_LeftPriority.Add(')', 80);
}
if (m_RightPriority.Count == 0)
{
m_RightPriority.Add('=', 0);
m_RightPriority.Add('(', 80);
m_RightPriority.Add('*', 40);
m_RightPriority.Add('/', 40);
m_RightPriority.Add('^', 60);
m_RightPriority.Add('+', 20);
m_RightPriority.Add('-', 20);
m_RightPriority.Add(')', 10);
}
}
#endregion
#region 内部方法
/// <summary>
/// 判断字符是否为运算符
/// </summary>
/// <param name="ch">待判断的字符</param>
/// <returns>如果是运算符,返回True,否则返回False</returns>
private static bool IsOperator(char ch)
{
if (ch == '(' || ch == ')' || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^')
{
return true;
}
return false;
}
/// <summary>
/// 判断运算符的优先级
/// </summary>
/// <param name="op1">第1个运算符</param>
/// <param name="op2">第2个运算符</param>
/// <returns>优先级:op1大于op2,返回1,op1等于op2-返回0,op1小于op2,返回-1</returns>
private static int Precede(char op1, char op2)
{
return m_LeftPriority[op1].CompareTo(m_RightPriority[op2]);
}
/// <summary>
/// 操作数进栈
/// </summary>
/// <param name="operand"></param>
private static void PushOperand(double operand)
{
m_Stack.Push(operand);
}
/// <summary>
/// 获取栈中最近的两个操作数
/// </summary>
/// <param name="operand1">第1个操作数</param>
/// <param name="operand2">第2个操作数</param>
private static bool GetTwoOperands(ref double operand1, ref double operand2)
{
bool ret = true;
if (m_Stack.Count == 0)
{
// 表达式有误
m_Stack.Clear();
ret = false;
}
operand1 = m_Stack.Pop();
if (m_Stack.Count == 0)
{
// 表达式有误
m_Stack.Clear();
ret = false;
}
operand2 = m_Stack.Pop();
return ret;
}
/// <summary>
/// 计算一次结果
/// </summary>
/// <param name="op">操作符</param>
private static bool Calculate(char op)
{
double operand1 = 0, operand2 = 0, result = 0;
bool ret = GetTwoOperands(ref operand1, ref operand2);
if (!ret)
{
ret = false;
return ret;
}
switch (op)
{
case '+': result = operand2 + operand1; break;
case '-': result = operand2 - operand1; break;
case '*': result = operand2 * operand1; break;
case '^': result = System.Math.Pow(operand2, operand1); break;
case '/':
if (operand1 == 0)
{
// 被0除
m_Stack.Clear();
ret = false;
}
else
{
result = operand2 / operand1;
}
break;
}
m_Stack.Push(result);
return ret;
}
#endregion
#region 公共方法
/// <summary>
/// 将中缀表达式转换成后缀表达式
/// </summary>
/// <param name="expression">中缀表达式</param>
/// <returns>后缀表达式</returns>
public static string TransExpression(string expression)
{
Stack<char> s = new Stack<char>();
s.Push('=');
int index = 0;
string ret = string.Empty;
while (index < expression.Length)
{
char ch = expression[index];
if (!IsOperator(ch))
{
while (index < expression.Length && expression[index] >= '0' && expression[index] <= '9')
{
ret += expression[index];
index++;
}
ret += '#';
}
else
{
switch (Precede(s.Peek(), ch))
{
case -1:
s.Push(ch);
index++;
break;
case 0:
s.Pop();
index++;
break;
case 1:
ret += s.Pop();
break;
}
}
}
while (s.Peek() != '=')
{
ret += s.Pop();
}
return ret;
}
/// <summary>
/// 计算表达式的值(无需带=号)
/// </summary>
/// <param name="expression">待计算的表达式</param>
/// <returns>表达式的值</returns>
public static double? Calculate(string expression)
{
double operand;
m_Stack.Clear();
string exp = TransExpression(expression);
exp += ' ';
int index = 0;
char ch = exp[index];
try
{
while (ch != ' ')
{
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^')
{
bool ret = Calculate(ch);
if (!ret)
{
return null;
}
index++;
ch = exp[index];
}
else if (ch == '#')
{
index++;
ch = exp[index];
}
else
{
operand = 0;
while (ch >= '0' && ch <= '9')
{
operand = operand * 10 + Convert.ToDouble(ch.ToString());
index++;
ch = exp[index];
}
m_Stack.Push(operand);
}
}
if (m_Stack.Count == 0)
{
// 表达式有误
return null;
}
double d = m_Stack.Pop();
m_Stack.Clear();
return d;
}
catch
{
return null;
}
}
#endregion
}
}
3.24点计算类
//-----------------------------------------------------------------------------
//
// 算法:24点计算类
//
// 版权所有(C) Snowdust
// 个人博客 http://blog.csdn.net/snowdust & http://snowdust.cnblogs.com
// MSN & Email snowdust77@sina.com
//
// 此源代码可免费用于各类软件(含商业软件)
// 允许对此代码的进一步修改与开发
// 但必须完整保留此版权信息
//
// 调用方法如下:
//
// 1.GetTwentyFourPointResultList(int[] array)
// 返回List<string>类型的所有结果列表
//
// 2.GetTwentyFourPointResultString(int[] array)
// 只返回一条结果
//
// 版本历史:
// V0.1 2010-01-21 摘要:首次创建
//
//-----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
namespace Arithmetic
{
public class TwentyFourPoint
{
#region 定义变量
/// <summary>
/// 表达式类型
/// 其中{0}{1}{2}{3}将会替换成数值,{5}{6}{7}替换成运算符(+-*/)
/// </summary>
protected static string[] m_Expression = new string[] {
"{0}{4}{1}{5}{2}{6}{3}", // 类型1: 1+2*3/4
"({0}{4}{1}){5}{2}{6}{3}", // 类型2: (1+2)*3/4
"({0}{4}{1}{5}{2}){6}{3}", // 类型3: (1+2*3)/4
"(({0}{4}{1}){5}{2}){6}{3}", // 类型4: ((1+2)*3)/4
"({0}{4}({1}{5}{2})){6}{3}", // 类型5: (1+(2*3))/4
"{0}{4}({1}{5}{2}){6}{3}", // 类型6: 1+(2*3)/4
"{0}{4}({1}{5}{2}{6}{3})", // 类型7: 1+(2*3/4)
"{0}{4}(({1}{5}{2}){6}{3})", // 类型8: 1+((2*3)/4)
"{0}{4}({1}{5}({2}{6}{3}))", // 类型9: 1+(2*(3/4))
"{0}{4}{1}{5}({2}{6}{3})", // 类型10:1+2*(3/4)
"({0}{4}{1}){5}({2}{6}{3})" // 类型11:(1+2)*(3/4)
};
/// <summary>
/// 运算符类型
/// </summary>
protected static string[] m_Operator = new string[] { "+", "-", "*", "/" };
/// <summary>
/// 运算结果为24
/// </summary>
protected static int m_ObjectNumber = 24;
/// <summary>
/// 结果误差
/// </summary>
protected static double m_Error = 0.0001;
#endregion
#region 公共方法
/// <summary>
/// 计算24点的结果
/// </summary>
/// <param name="array">数值数组</param>
/// <param name="getAllResult">是否获取所有结果</param>
/// <returns>结果列表</returns>
public static List<string> GetResultList(int[] array, bool getAllResult)
{
if (array.Length != 4)
{
return null;
}
List<string> m_Result = new List<string>();
List<int[]> m_OperandPermutation = Arithmetic.PermutationAndCombination<int>.GetPermutation(array);
for (int i = 0; i < m_OperandPermutation.Count; i++)
{
for (int op1 = 0; op1 < 4; op1++)
{
for (int op2 = 0; op2 < 4; op2++)
{
for (int op3 = 0; op3 < 4; op3++)
{
for (int k = 0; k < m_Expression.Length; k++)
{
string str = string.Format(m_Expression[k], m_OperandPermutation[i][0], m_OperandPermutation[i][1], m_OperandPermutation[i][2], m_OperandPermutation[i][3], m_Operator[op1], m_Operator[op2], m_Operator[op3]);
double? d = Arithmetic.Calculator.Calculate(str);
if (d != null && d.Value >= m_ObjectNumber - m_Error && d.Value <= m_ObjectNumber + m_Error) //由于浮点数操作可能会导致误差,因此忽略小于0.0001的误差
{
if (!m_Result.Contains(str))
{
m_Result.Add(str);
if (!getAllResult)
{
return m_Result;
}
}
}
}
}
}
}
}
return m_Result;
}
/// <summary>
/// 计算24点的结果(返回所有解的记录)
/// </summary>
/// <param name="array">数值数组</param>
/// <returns>结果列表</returns>
public static List<string> GetResultList(int[] array)
{
return GetResultList(array, true);
}
/// <summary>
/// 计算24点的结果(如果有解,只返回一条记录)
/// </summary>
/// <param name="array">数值数组</param>
/// <returns>结果字符串</returns>
public static string GetResultString(int[] array)
{
List<string> list = GetResultList(array, false);
if (list.Count == 1)
{
return list[0];
}
else
{
return string.Empty;
}
}
#endregion
}
}
//
// 算法:24点计算类
//
// 版权所有(C) Snowdust
// 个人博客 http://blog.csdn.net/snowdust & http://snowdust.cnblogs.com
// MSN & Email snowdust77@sina.com
//
// 此源代码可免费用于各类软件(含商业软件)
// 允许对此代码的进一步修改与开发
// 但必须完整保留此版权信息
//
// 调用方法如下:
//
// 1.GetTwentyFourPointResultList(int[] array)
// 返回List<string>类型的所有结果列表
//
// 2.GetTwentyFourPointResultString(int[] array)
// 只返回一条结果
//
// 版本历史:
// V0.1 2010-01-21 摘要:首次创建
//
//-----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
namespace Arithmetic
{
public class TwentyFourPoint
{
#region 定义变量
/// <summary>
/// 表达式类型
/// 其中{0}{1}{2}{3}将会替换成数值,{5}{6}{7}替换成运算符(+-*/)
/// </summary>
protected static string[] m_Expression = new string[] {
"{0}{4}{1}{5}{2}{6}{3}", // 类型1: 1+2*3/4
"({0}{4}{1}){5}{2}{6}{3}", // 类型2: (1+2)*3/4
"({0}{4}{1}{5}{2}){6}{3}", // 类型3: (1+2*3)/4
"(({0}{4}{1}){5}{2}){6}{3}", // 类型4: ((1+2)*3)/4
"({0}{4}({1}{5}{2})){6}{3}", // 类型5: (1+(2*3))/4
"{0}{4}({1}{5}{2}){6}{3}", // 类型6: 1+(2*3)/4
"{0}{4}({1}{5}{2}{6}{3})", // 类型7: 1+(2*3/4)
"{0}{4}(({1}{5}{2}){6}{3})", // 类型8: 1+((2*3)/4)
"{0}{4}({1}{5}({2}{6}{3}))", // 类型9: 1+(2*(3/4))
"{0}{4}{1}{5}({2}{6}{3})", // 类型10:1+2*(3/4)
"({0}{4}{1}){5}({2}{6}{3})" // 类型11:(1+2)*(3/4)
};
/// <summary>
/// 运算符类型
/// </summary>
protected static string[] m_Operator = new string[] { "+", "-", "*", "/" };
/// <summary>
/// 运算结果为24
/// </summary>
protected static int m_ObjectNumber = 24;
/// <summary>
/// 结果误差
/// </summary>
protected static double m_Error = 0.0001;
#endregion
#region 公共方法
/// <summary>
/// 计算24点的结果
/// </summary>
/// <param name="array">数值数组</param>
/// <param name="getAllResult">是否获取所有结果</param>
/// <returns>结果列表</returns>
public static List<string> GetResultList(int[] array, bool getAllResult)
{
if (array.Length != 4)
{
return null;
}
List<string> m_Result = new List<string>();
List<int[]> m_OperandPermutation = Arithmetic.PermutationAndCombination<int>.GetPermutation(array);
for (int i = 0; i < m_OperandPermutation.Count; i++)
{
for (int op1 = 0; op1 < 4; op1++)
{
for (int op2 = 0; op2 < 4; op2++)
{
for (int op3 = 0; op3 < 4; op3++)
{
for (int k = 0; k < m_Expression.Length; k++)
{
string str = string.Format(m_Expression[k], m_OperandPermutation[i][0], m_OperandPermutation[i][1], m_OperandPermutation[i][2], m_OperandPermutation[i][3], m_Operator[op1], m_Operator[op2], m_Operator[op3]);
double? d = Arithmetic.Calculator.Calculate(str);
if (d != null && d.Value >= m_ObjectNumber - m_Error && d.Value <= m_ObjectNumber + m_Error) //由于浮点数操作可能会导致误差,因此忽略小于0.0001的误差
{
if (!m_Result.Contains(str))
{
m_Result.Add(str);
if (!getAllResult)
{
return m_Result;
}
}
}
}
}
}
}
}
return m_Result;
}
/// <summary>
/// 计算24点的结果(返回所有解的记录)
/// </summary>
/// <param name="array">数值数组</param>
/// <returns>结果列表</returns>
public static List<string> GetResultList(int[] array)
{
return GetResultList(array, true);
}
/// <summary>
/// 计算24点的结果(如果有解,只返回一条记录)
/// </summary>
/// <param name="array">数值数组</param>
/// <returns>结果字符串</returns>
public static string GetResultString(int[] array)
{
List<string> list = GetResultList(array, false);
if (list.Count == 1)
{
return list[0];
}
else
{
return string.Empty;
}
}
#endregion
}
}
主窗体的代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace AppMain
{
public partial class MainForm : Form
{
#region 声明扑克牌API
// cards.dll文件位于System32目录下
[DllImport("cards.dll")]
public static extern bool cdtInit(ref int width, ref int height);
[DllImport("cards.dll")]
public static extern void cdtTerm();
[DllImport("cards.dll")]
public static extern bool cdtDraw(IntPtr hdc, int x, int y, int card, int mode, long color);
private IntPtr m_HDC = new IntPtr();
#endregion
#region 定义变量
/// <summary>
/// 四个数
/// </summary>
private int[] m_FourNumber = new int[4];
/// <summary>
/// 四种花色
/// </summary>
private int[] m_CardsColor = new int[4];
/// <summary>
/// 计算结果
/// </summary>
private string m_Result = string.Empty;
#endregion
#region 自定义方法
/// <summary>
/// 初始化
/// </summary>
private void Init()
{
//清除结果
this.txt_Result.Text = string.Empty;
//随机生成四个数,直至有解
Random rand = new Random();
m_Result = string.Empty;
while (m_Result == string.Empty)
{
for (int i = 0; i < m_FourNumber.Length; i++)
{
m_FourNumber[i] = rand.Next(10) + 1;
}
m_Result = Arithmetic.TwentyFourPoint.GetResultString(m_FourNumber);
}
//随机生成扑克牌的花色
for (int i = 0; i < m_FourNumber.Length; i++)
{
m_CardsColor[i] = rand.Next(4);
}
//重绘以正确显示扑克牌
this.Refresh();
}
/// <summary>
/// 绘制四张扑克牌
/// </summary>
private void DrawCards()
{
for (int i = 0; i < this.m_FourNumber.Length; i++)
{
if (m_FourNumber[i] > 0)
{
cdtDraw(m_HDC, 25 + i * 90, 70, m_FourNumber[i] * 4 - 4 + m_CardsColor[i], 0, 1);
}
}
}
#endregion
#region 事件处理
public MainForm()
{
InitializeComponent();
int width, height;
width = 0; height = 0;
cdtInit(ref width, ref height); // 初始化扑克牌
}
private void MainForm_Load(object sender, EventArgs e)
{
this.Icon = Properties.Resources.App;
Init();
}
private void TwentyFourPointForm_FormClosing(object sender, FormClosingEventArgs e)
{
cdtTerm();
}
// 重写窗体的OnPaint方法
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
m_HDC = g.GetHdc();
g.ReleaseHdc(m_HDC);
DrawCards();
}
private void btn_Build_Click(object sender, EventArgs e)
{
Init();
}
private void btn_Setup_Click(object sender, EventArgs e)
{
SetupForm form = new SetupForm();
form.FourNumber = m_FourNumber;
if (form.ShowDialog() == DialogResult.OK)
{
m_FourNumber = form.FourNumber;
m_Result = Arithmetic.TwentyFourPoint.GetResultString(m_FourNumber);
this.txt_Result.Text = m_Result;
this.Refresh();
if (m_Result == string.Empty)
{
MessageBox.Show("无解");
}
}
}
private void btn_Result_Click(object sender, EventArgs e)
{
this.txt_Result.Text = m_Result;
}
#endregion
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace AppMain
{
public partial class MainForm : Form
{
#region 声明扑克牌API
// cards.dll文件位于System32目录下
[DllImport("cards.dll")]
public static extern bool cdtInit(ref int width, ref int height);
[DllImport("cards.dll")]
public static extern void cdtTerm();
[DllImport("cards.dll")]
public static extern bool cdtDraw(IntPtr hdc, int x, int y, int card, int mode, long color);
private IntPtr m_HDC = new IntPtr();
#endregion
#region 定义变量
/// <summary>
/// 四个数
/// </summary>
private int[] m_FourNumber = new int[4];
/// <summary>
/// 四种花色
/// </summary>
private int[] m_CardsColor = new int[4];
/// <summary>
/// 计算结果
/// </summary>
private string m_Result = string.Empty;
#endregion
#region 自定义方法
/// <summary>
/// 初始化
/// </summary>
private void Init()
{
//清除结果
this.txt_Result.Text = string.Empty;
//随机生成四个数,直至有解
Random rand = new Random();
m_Result = string.Empty;
while (m_Result == string.Empty)
{
for (int i = 0; i < m_FourNumber.Length; i++)
{
m_FourNumber[i] = rand.Next(10) + 1;
}
m_Result = Arithmetic.TwentyFourPoint.GetResultString(m_FourNumber);
}
//随机生成扑克牌的花色
for (int i = 0; i < m_FourNumber.Length; i++)
{
m_CardsColor[i] = rand.Next(4);
}
//重绘以正确显示扑克牌
this.Refresh();
}
/// <summary>
/// 绘制四张扑克牌
/// </summary>
private void DrawCards()
{
for (int i = 0; i < this.m_FourNumber.Length; i++)
{
if (m_FourNumber[i] > 0)
{
cdtDraw(m_HDC, 25 + i * 90, 70, m_FourNumber[i] * 4 - 4 + m_CardsColor[i], 0, 1);
}
}
}
#endregion
#region 事件处理
public MainForm()
{
InitializeComponent();
int width, height;
width = 0; height = 0;
cdtInit(ref width, ref height); // 初始化扑克牌
}
private void MainForm_Load(object sender, EventArgs e)
{
this.Icon = Properties.Resources.App;
Init();
}
private void TwentyFourPointForm_FormClosing(object sender, FormClosingEventArgs e)
{
cdtTerm();
}
// 重写窗体的OnPaint方法
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
m_HDC = g.GetHdc();
g.ReleaseHdc(m_HDC);
DrawCards();
}
private void btn_Build_Click(object sender, EventArgs e)
{
Init();
}
private void btn_Setup_Click(object sender, EventArgs e)
{
SetupForm form = new SetupForm();
form.FourNumber = m_FourNumber;
if (form.ShowDialog() == DialogResult.OK)
{
m_FourNumber = form.FourNumber;
m_Result = Arithmetic.TwentyFourPoint.GetResultString(m_FourNumber);
this.txt_Result.Text = m_Result;
this.Refresh();
if (m_Result == string.Empty)
{
MessageBox.Show("无解");
}
}
}
private void btn_Result_Click(object sender, EventArgs e)
{
this.txt_Result.Text = m_Result;
}
#endregion
}
}
下载地址1:点此下载
下载地址2:点此下载