Java 中的叉积计算器
我正在阅读 Norvig 的有关 AIP 的书。其中有一个关于编写叉积函数的练习 -
(defun cross-product (fn list-1 list-2)
(mappend #'(lambda (y)
(mapcar #'(lambda (x)
(funcall fn y x))
list-2))
list-1))
(defun mappend (fn the-list)
(if (null the-list)
nil
(append (funcall fn (first the-list))
(mappend fn (rest the-list)))))
我正在尝试用 Java 编写一个实现 -
interface Function<T1, T2, T3> {
public T3 function(T1 t1, T2 t2);
}
public class CrossProduct<T1, T2> {
private List<T1> list1;
private List<T2> list2;
public CrossProduct(List<T1> t1, List<T2> t2) {
this.list1 = t1;
this.list2 = t2;
}
public <T3> List<T3> calculate(Function<T1, T2, T3> fn) {
List product = new ArrayList();
for (int i = 0; i < list1.size(); i++)
for (int j = 0; j < list2.size(); j++)
product.add(fn.function(list1.get(i), list2.get(j)));
return product;
}
}
用法 -
@Test
public void testWithStrings() {
List<String> list1 = new ArrayList<String>();
list1.add("6");
list1.add("8");
List<String> list2 = new ArrayList<String>();
list2.add("2");
list2.add("3");
List<String> product = new CrossProduct<String, String>(list1, list2)
.<String> calculate(new Function<String, String, String>() {
public String function(String x, String y) {
return (String) x + (String) y;
}
});
Assert.assertEquals("62", product.get(0));
Assert.assertEquals("63", product.get(1));
Assert.assertEquals("82", product.get(2));
Assert.assertEquals("83", product.get(3));
}
有更好的方法吗?
I am working my way through Norvig's book on AIP. There is an exercise in it on writing a cross-product function -
(defun cross-product (fn list-1 list-2)
(mappend #'(lambda (y)
(mapcar #'(lambda (x)
(funcall fn y x))
list-2))
list-1))
(defun mappend (fn the-list)
(if (null the-list)
nil
(append (funcall fn (first the-list))
(mappend fn (rest the-list)))))
I am trying to write an implementation in Java -
interface Function<T1, T2, T3> {
public T3 function(T1 t1, T2 t2);
}
public class CrossProduct<T1, T2> {
private List<T1> list1;
private List<T2> list2;
public CrossProduct(List<T1> t1, List<T2> t2) {
this.list1 = t1;
this.list2 = t2;
}
public <T3> List<T3> calculate(Function<T1, T2, T3> fn) {
List product = new ArrayList();
for (int i = 0; i < list1.size(); i++)
for (int j = 0; j < list2.size(); j++)
product.add(fn.function(list1.get(i), list2.get(j)));
return product;
}
}
Usage -
@Test
public void testWithStrings() {
List<String> list1 = new ArrayList<String>();
list1.add("6");
list1.add("8");
List<String> list2 = new ArrayList<String>();
list2.add("2");
list2.add("3");
List<String> product = new CrossProduct<String, String>(list1, list2)
.<String> calculate(new Function<String, String, String>() {
public String function(String x, String y) {
return (String) x + (String) y;
}
});
Assert.assertEquals("62", product.get(0));
Assert.assertEquals("63", product.get(1));
Assert.assertEquals("82", product.get(2));
Assert.assertEquals("83", product.get(3));
}
Is there a better way of doing this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
以这种方式定义 CrossProduct 类似乎有点武断:为什么 list args 是成员变量,而 fn 是方法参数?事实上,为什么
CrossProduct
是一个类呢?叉积是一个
列表,但它不是列表的子类型,因为给定的列表可以叉积构造的
函数。在我看来,将“交叉产品”视为一种类型是不自然的。
我可能会做类似的事情
如果您确实想出于某种原因定义一个类 CrossProduct(例如,按照 salman 建议实现惰性求值),我会说将所有三个参数作为成员变量更加面向对象,并让类实现
List
,例如It seems a little arbitrary to define your
CrossProduct
class that way: why are the list args member variables, whereas thefn
is a method parameter? In fact, why isCrossProduct
a class at all? A cross productis a
list, but it's not a subtype of list, since a given list could bothcrossproduct
function.It's not natural to think of "cross product" as a type, IMO.
I would probably do something like
If you did want to define a class
CrossProduct
for some reason (e.g. to implement lazy evaluation as salman suggested), I would say it's more OO to have all three args as member variables, and have the class implementList
, e.g.我不知道你到底想改进哪些参数。但是,我想说我不喜欢 N*M 列表大小,因为它可能太大。如果我知道结果列表可以是不可变的,那么我会实现自己的列表,它仅在
result.get(i* 时计算
被调用。所以我没有保留一个很长的列表(如果需要的话也许只是一个小缓存)。product(l1(i), l2(j))
M+j-1)I don't know exactly which parameters you would like to improve. However, I would say I don't like N*M list size since it can be too big. If I knew that the result list can be immutable, then I would implement my own List which only calculates
product(l1(i), l2(j))
whenresult.get(i*M+j-1)
is called. So I have not keep a long list (perhaps just a small cache if needed).