此代码解决了http://www.programgood.net/2011/01/13/DynamicOperatorsGuernseyChallenge.aspx
中概述的有趣谜题问题:这里似乎有很多重复。干(不要重复自己)原则让人想到这里。有人看到重构吗?
string opZ = "";
string opA = "";
string opB = "";
string opC = "";
string opD = "";
for (int h = 1; h <= 2; h++) // making the first number positive or negative
{
if (h == 1) opZ = "";
if (h == 2) opZ = "-";
for (int i = 1; i <= 4; i++)
{
if (i == 1) opA = "*";
if (i == 2) opA = "/";
if (i == 3) opA = "+";
if (i == 4) opA = "-";
for (int j = 1; j <= 4; j++)
{
if (j == 1) opB = "*";
if (j == 2) opB = "/";
if (j == 3) opB = "+";
if (j == 4) opB = "-";
for (int k = 1; k <= 4; k++)
{
if (k == 1) opC = "*";
if (k == 2) opC = "/";
if (k == 3) opC = "+";
if (k == 4) opC = "-";
for (int l = 1; l <= 4; l++)
{
if (l == 1) opD = "*";
if (l == 2) opD = "/";
if (l == 3) opD = "+";
if (l == 4) opD = "-";
string expression = opZ + 1 + opA + 3 + opB + 5 + opC + 7 + opD + 9;
DataTable dummy = new DataTable();
double result = Convert.ToDouble(dummy.Compute(expression, string.Empty));
if (result == 3)
Debug.WriteLine(expression + " = 3");
if (result == 47)
Debug.WriteLine(expression + " = 47");
if (result == 18)
Debug.WriteLine(expression + " = 18");
}
}
}
}
}
答案 0 :(得分:3)
嗯,第一个明显的重构是拥有一组运算符:
String[] operators = { null, "*", "/", "+", "-" };
然后使用:
opC = operators[j]; // etc
(我个人使用的循环从0到3而不是1到4 - 这是更惯用的IMO,但这是另一回事。)
然后就是建立排列的方法。我实际上使用LINQ:
string[] prefixes = { "", "-" };
string[] operators = { "*", "/", "+", "-" };
var expressions = from prefix in prefixes
from opA in operators
from opB in operators
from opC in operators
from opD in operators
select prefix + 1 + opA + 3 + opB + 5 + opC + 7 + opD + 9;
foreach (string expression in expressions)
{
...
}
答案 1 :(得分:1)
char[] ops = new [] {'*','/','+','-'};
foreach(string opA in ops)
foreach(string opB in ops)
foreach(string opC in ops)
foreach(string opD in ops)
foreach(string opZ in new []{'-',' '}) {
string expression = opZ + 1 + opA + 3 + opB + 5 + opC + 7 + opD + 9;
DataTable dummy = new DataTable();
double result = Convert.ToDouble(dummy.Compute(expression, string.Empty));
if (result == 3)
Debug.WriteLine(expression + " = 3");
if (result == 47)
Debug.WriteLine(expression + " = 47");
if (result == 18)
Debug.WriteLine(expression + " = 18");
}
答案 2 :(得分:0)
我认为在使用DataTable.Compute
时没有真正的意义,但是
var calculator = new DataTable () ;
var operators = "*/+-" ;
for (int i = 0 ; i < 0x200 ; ++i)
{
var value = calculator.Compute (String.Format ("{0}1{1}3{2}5{3}7{4}9",
(i & 0x100) != 0 ? "-" : "",
operators[(i >> 0) & 3],
operators[(i >> 2) & 3],
operators[(i >> 4) & 3],
operators[(i >> 6) & 3]), String.Empty) ;
...
}
否则,如果有点更深奥,这肯定会更快:
var opstrings = "+-*/" ;
var operators = new Func<int, int, int>[] {
(a, b) => a + b,
(a, b) => a - b,
(a, b) => a * b,
(a, b) => a / b, } ;
for (int i = 0 ; i < 0x200 ; ++i)
{
var stack = 0 ; // seed value
var last = 0 ; // imitate + for lowest precedence
var value =(i & 0x100) != 0 ? -1 : 1 ;
for (int j = 0 ; j < 5 ; ++j) // extra item to force last reduction
{
var oper = (i >> j * 2) & 3 ; // "input" operator
var input = 3 + j * 2 ; // "input" number
if (oper / 2 <= last / 2) // reduce below top?
{
stack = operators[last] (stack, value) ;
last = oper ; // shift operator
value = input ; // shift number
}
else // reduce top
value = operators[oper] (value, input) ;
}
var result = stack ;
if (result == 3 || result == 47 || result == 18)
Debug.WriteLine ("{0}1{1}3{2}5{3}7{4}9 = {5}",
(i & 0x100) != 0 ? "-" : "",
opstrings[(i >> 0) & 3],
opstrings[(i >> 2) & 3],
opstrings[(i >> 4) & 3],
opstrings[(i >> 6) & 3],
result) ;
}