我遇到this question,OP希望改进以下if-block。我将此作为一个新问题打开,因为我正在寻找这种问题的更通用的解决方案。
public int fightMath(int one, int two) {
if(one == 0 && two == 0) { result = 0; }
else if(one == 0 && two == 1) { result = 0; }
else if(one == 0 && two == 2) { result = 1; }
else if(one == 0 && two == 3) { result = 2; }
else if(one == 1 && two == 0) { result = 0; }
else if(one == 1 && two == 1) { result = 0; }
else if(one == 1 && two == 2) { result = 2; }
else if(one == 1 && two == 3) { result = 1; }
else if(one == 2 && two == 0) { result = 2; }
else if(one == 2 && two == 1) { result = 1; }
else if(one == 2 && two == 2) { result = 3; }
else if(one == 2 && two == 3) { result = 3; }
else if(one == 3 && two == 0) { result = 2; }
else if(one == 3 && two == 1) { result = 1; }
else if(one == 3 && two == 2) { result = 3; }
else if(one == 3 && two == 3) { result = 3; }
return result;
}
现在有n^k
种可能获得结果,n = 2 and k = 4
。
一些答案建议使用多阵列作为表来减少if-jungle。
但我想知道如何解决大n和k这样的问题?因为if,switch和建议的数组方法的解决方案不能很好地扩展,并且应该避免在代码中键入类似的东西。
如果我考虑组合问题,就必须有一种方法来评估它们。
答案 0 :(得分:4)
它只是一个数据表。问题的答案可以通过多个键找到。返回数据库表中保存的一些数据并没有什么不同,数据库表本身可能很大,可能跨越多个表。
答案 1 :(得分:2)
有两种方法可以解决这个问题:
基于数据。例如,您可以创建一个HashMap,将这对值映射到结果。
class Pair {
int one, two;
//Generate hashcode and equals
}
Map<Pair, Integer> counts = new HashMap<>();
基于模式。确定可用于确定新值的规则/公式。
这显然更好,但依赖于能够确定涵盖所有案例的规则。
答案 2 :(得分:1)
我想知道如何解决大n和k这样的问题。
由于输出是任意确定的(游戏设计师的突发奇想)而不是数学(公式),因此无法保证任何模式。因此,唯一的通用解决方案是某种查找表。
基本上,问题类似于要求执行f(a,b) - &gt;的程序。 c映射,但您事先并不知道任何数据 - 而是在运行时提供。该程序可以处理数据并找到模式/公式(可能不存在),也可以构建查找表。
就我个人而言,我认为更改逻辑以操作意图(因此阅读代码解释了攻击是如何工作的)而不是实际结果(枚举输入列表和匹配输出)更为明确。而不是构建if-jungle或查找表,根据您希望逻辑的工作方式构建代码。 JAB's enum-based solution明确地表达了战斗逻辑,这使得更容易看到添加新功能的位置并且更容易看到错误(查找表中的一个错误在检查时显然是错误的)。查找表可能是一种优化,但只有在分析器这样说时才需要。
答案 3 :(得分:0)
看看你的问题和原来的问题,两个玩家的输入和输出之间似乎没有可推断的模式(也许我错了)。鉴于此,唯一的选择是&#34; if-jungle&#34;你提到或使用数据结构。
为了解决大n和k值这样的问题,我的建议是创建一个规则来确定输出(无人,一个或两个玩家命中),但要确保这个规则不容易被推导到玩家们。你可以通过使规则成为转弯数的函数来做到这一点(例如,如果两个玩家在转弯#1上按下按钮1,则输出将与在转弯#2处采取相同动作的输出不同。)