我发现我经常进行递归调用,只是为了对参数重新排序.
例如,这是我针对endOther
from codingbat.com的解决方案:
Given two strings, return
true
if either of the strings appears at the very end of the other string, ignoring upper/lower case differences (in other words, the computation should not be “case sensitive”). Note:str.toLowerCase()
returns the lowercase version of a string.
public boolean endOther(String a, String b) {
return a.length() < b.length() ? endOther(b, a)
: a.toLowerCase().endsWith(b.toLowerCase());
}
我对递归非常满意,但是我当然可以理解为什么有些人可能会反对它.
此递归技术有两种明显的替代方法:
传统上交换a和b
public boolean endOther(String a, String b) {
if (a.length() < b.length()) {
String t = a;
a = b;
b = t;
}
return a.toLowerCase().endsWith(b.toLowerCase());
}
>在不通过引用传递的Java之类的语言中不方便
>很多代码只是要做一个简单的操作
>一个额外的if语句破坏了“流程”
重复代码
public boolean endOther(String a, String b) {
return (a.length() < b.length())
? b.toLowerCase().endsWith(a.toLowerCase())
: a.toLowerCase().endsWith(b.toLowerCase());
}
>明确的对称性可能是一件好事(不是吗?)
>好主意,除非重复的代码非常简单
> …尽管在这种情况下,您可以摆脱三元而只是||这两个表达
所以我的问题是:
>这三种技术有名称吗? (还有更多吗?)
>他们所取得的成就是否有名字? (例如“参数标准化”?)
>是否有关于使用哪种技术的官方建议(何时)?
>我可能还错过了哪些其他利弊?
另一个例子
为了使讨论更多地集中在技术上,而不是特定的编码问题,这是另一个例子,我觉得递归比一堆if-else,交换或重复代码更为优雅.
// sorts 3 values and return as array
static int[] sort3(int a, int b, int c) {
return
(a > b) ? sort3(b, a, c) :
(b > c) ? sort3(a, c, b) :
new int[] { a, b, c };
}
递归和三元运算符对我的困扰不如对某些人的困扰.老实说,我相信上面的代码是人们可能会写的最好的纯Java解决方案.随时向我展示.
解决方法:
首先,让我们确定代码重复通常不是一个好主意.
因此,无论采用哪种解决方案,该方法的逻辑仅应编写一次,并且我们需要一种交换参数的方法,以免干扰逻辑.
我看到了三种通用的解决方案:
>您的第一个递归(使用if或条件运算符).
> swap –在Java中是个问题,但可能适用于其他语言.
>两种单独的方法(如@Ha解决方案中的方法),其中一种充当逻辑的实现,另一种充当接口,在这种情况下可以对参数进行分类.
我不知道这些解决方案中哪一个是最好的.但是,我注意到某些算法通常将(1)作为惯用解,例如Euklid的算法,用于计算两个数字的GCD.
我通常不赞成交换解决方案(2),因为它增加了一个额外的调用,该调用实际上与算法无关.现在,从技术上讲这不是问题-我怀疑它是否比使用任何不错的编译器的效率(1)或(3)低.但这增加了心理上的颠簸.
解决方案(3)使我感到工程过度,尽管除了要阅读更多文字之外,我无法想到任何批评.通常,我不喜欢后缀为“ Impl”的任何方法所引入的额外间接.
总之,尽管实际上我在类似情况下使用了(3),但在大多数情况下我还是更喜欢(1).