将这种递归Python方法翻译成Java的最佳方法是什么?
在另一个问题中我提供了一个很好的答案,涉及为中国邮递员问题生成某些集合。
提供的答案是:
def get_pairs(s):
if not s: yield []
else:
i = min(s)
for j in s - set([i]):
for r in get_pairs(s - set([i, j])):
yield [(i, j)] + r
for x in get_pairs(set([1,2,3,4,5,6])):
print x
这将输出所需的结果:
[(1, 2), (3, 4), (5, 6)]
[(1, 2), (3, 5), (4, 6)]
[(1, 2), (3, 6), (4, 5)]
[(1, 3), (2, 4), (5, 6)]
[(1, 3), (2, 5), (4, 6)]
[(1, 3), (2, 6), (4, 5)]
[(1, 4), (2, 3), (5, 6)]
[(1, 4), (2, 5), (3, 6)]
[(1, 4), (2, 6), (3, 5)]
[(1, 5), (2, 3), (4, 6)]
[(1, 5), (2, 4), (3, 6)]
[(1, 5), (2, 6), (3, 4)]
[(1, 6), (2, 3), (4, 5)]
[(1, 6), (2, 4), (3, 5)]
[(1, 6), (2, 5), (3, 4)]
这确实展示了 Python 的表达能力,因为这几乎正是我为算法编写伪代码的方式。我特别喜欢yield 的使用以及集合被视为一等公民的方式。
然而,这就是我的问题。
最好的方法是什么:
1. 在 Java 中复制yield return 构造的功能?最好维护一个列表并将我的部分结果附加到该列表中吗?你会如何处理yield关键字。
2.处理集合的处理?我知道我可能可以使用实现 Set 接口的 Java 集合之一,然后使用诸如 removeAll() 之类的东西来给我一个集合差异。在这种情况下你会这么做吗?
最终,我希望在 Java 中将该方法简化为尽可能简洁和直接的方式。我认为该方法的 java 版本的返回类型可能会返回 int 数组列表或类似的内容。
当将此方法转换为 Java 时,您将如何处理上述情况?
In another question I was provided with a great answer involving generating certain sets for the Chinese Postman Problem.
The answer provided was:
def get_pairs(s):
if not s: yield []
else:
i = min(s)
for j in s - set([i]):
for r in get_pairs(s - set([i, j])):
yield [(i, j)] + r
for x in get_pairs(set([1,2,3,4,5,6])):
print x
This will output the desire result of:
[(1, 2), (3, 4), (5, 6)]
[(1, 2), (3, 5), (4, 6)]
[(1, 2), (3, 6), (4, 5)]
[(1, 3), (2, 4), (5, 6)]
[(1, 3), (2, 5), (4, 6)]
[(1, 3), (2, 6), (4, 5)]
[(1, 4), (2, 3), (5, 6)]
[(1, 4), (2, 5), (3, 6)]
[(1, 4), (2, 6), (3, 5)]
[(1, 5), (2, 3), (4, 6)]
[(1, 5), (2, 4), (3, 6)]
[(1, 5), (2, 6), (3, 4)]
[(1, 6), (2, 3), (4, 5)]
[(1, 6), (2, 4), (3, 5)]
[(1, 6), (2, 5), (3, 4)]
This really shows off the expressiveness of Python because this is almost exactly how I would write the pseudo-code for the algorithm. I especially like the usage of yield and and the way that sets are treated as first class citizens.
However, there in lies my problem.
What would be the best way to:
1.Duplicate the functionality of the yield return construct in Java? Would it instead be best to maintain a list and append my partial results to this list? How would you handle the yield keyword.
2.Handle the dealing with the sets? I know that I could probably use one of the Java collections which implements that implements the Set interface and then using things like removeAll() to give me a set difference. Is this what you would do in that case?
Ultimately, I'm looking to reduce this method into as concise and straightforward way as possible in Java. I'm thinking the return type of the java version of this method will likely return a list of int arrays or something similar.
How would you handle the situations above when converting this method into Java?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为了将生成器函数转换为 Java,您必须将其重新实现为 Iterable+Iterator。例如:
成为(警告:代码未经测试):
对于集合,我确实会使用
java.util.HashSet
。In order to translate a generator function to Java you have to reimplement it as a Iterable+Iterator. E.g.:
Becomes (warning: code is not tested):
For the sets I would indeed use
java.util.HashSet
.您可能想在 JVM 上运行它。为什么不使用 Scala?
我认为你可以将python代码翻译成scala中几乎相同的代码。比冗长的 java 东西好多了。最终它是 jvm 字节码,可以轻松地与您的 java 应用程序混合/协作。
You probably want to run it on a JVM. Why not use Scala?
I think you can translate the python code into almost the same kind of code in scala. Much better then the verbose java stuff. And it's jvm bytecode in the end which will easily blend in/cooperate with your java app.
这不是你所要求的,但我想尝试一下,所以这里有一个使用 LINQ 的 C# 解决方案:
实际上并不返回对,只是有序的整数列表,但是在这之后将其切成两半很容易。另外,很高兴看到 C# 可以与 Python 的简洁性相媲美。
测试一下:
输出:
归功于 Noldorin 对另一个问题的回答 LINQ 问题的一些想法。
This isn't what you asked for, but I wanted to try it out, so here's a solution in C# using LINQ:
Doesn't actually return pairs, just ordered lists of integers, but chopping it up by twos after this is easy. Also, nice to see that C# can rival the conciseness of Python.
Testing it out:
And the output:
Credit to Noldorin's answer to another LINQ question for some ideas.