2011-01-11 85 views
7

我不喜欢,我可以在Python处理列表的方式。它做任何递归解决方案看起来简单和干净。例如获得元素的所有排列在一个列表,在Python中的典型问题是这样的:在Java中有没有更好的方法来处理列表? (Python的和Java)

def permutation_recursion(numbers,sol): 
    if not numbers: 
     print "this is a permutation", sol 
    for i in range(len(numbers)): 
     permutation_recursion(numbers[:i] + numbers[i+1:], sol + [numbers[i]]) 

def get_permutations(numbers): 
    permutation_recursion(numbers,list()) 

if __name__ == "__main__": 
    get_permutations([1,2,3]) 

我喜欢的方式,我可以简单的做这样的事情 numbers[:i] + numbers[i+1:]sol + [numbers[i]]得到修改单的新实例

如果我尝试代码完全在Java中一样,它看起来像:

import java.util.ArrayList; 
import java.util.Arrays; 

class rec { 
    static void permutation_recursion(ArrayList<Integer> numbers, ArrayList<Integer> sol) { 
     if (numbers.size() == 0) 
      System.out.println("permutation="+Arrays.toString(sol.toArray())); 
     for(int i=0;i<numbers.size();i++) { 
      int n = numbers.get(i); 

      ArrayList<Integer> remaining = new ArrayList<Integer>(numbers); 
      remaining.remove(i); 

      ArrayList<Integer> sol_rec = new ArrayList<Integer>(sol); 
      sol_rec.add(n); 

      permutation_recursion(remaining,sol_rec); 
     } 
    } 
    static void get_permutation(ArrayList<Integer> numbers) { 
     permutation_recursion(numbers,new ArrayList<Integer>()); 
    } 
    public static void main(String args[]) { 
     Integer[] numbers = {1,2,3}; 
     get_permutation(new ArrayList<Integer>(Arrays.asList(numbers))); 
    } 
} 

要创建相同的递归我需要做的:

ArrayList<Integer> remaining = new ArrayList<Integer>(numbers); 
remaining.remove(i); 

ArrayList<Integer> sol_rec = new ArrayList<Integer>(sol); 
sol_rec.add(n); 

这是相当丑陋,它获取更多复杂的解决方案更糟糕。像在this example

所以我的问题是...有没有在Java API中的任何内建运算符或帮助函数,这将使该解决方案更“Pythonic”?

+3

总是有Jython :) – Seth 2011-01-11 20:15:42

+2

标题中的`more`是多余的 - 问题应该是有没有什么干净的方式来处理Java中的列表。而afaik,不 - 没有。 – 2011-02-04 00:29:10

回答

8

但是,这也就是为什么马丁·奥德斯基创建Scala。他甚至说,他对Scala的目标之一就是它是Java世界的Python。 Scala编译为Java字节码,并容易与Java编译类进行交互。

如果这不是一种选择,你可以看看在Commons Collection Library

+0

精确的+1。 – Nishant 2011-01-11 20:16:44

2

您可以使用列表的clone()功能,让他们的浅表副本。这样你就不必自己实例化一个新对象,但可以使用该副本。

ArrayList<Integer> remaining = remaining.clone().remove(i); 

除此之外,不,java没有列表的这些运算符。

0

嗨 1,你可以使用堆栈,这将更加得心应手。

2的for循环可以这样写: 为(个数n:数字)

1

阿帕奇百科全书解决了很多这类问题的。看看ArrayUtils做切片。由于各种原因,Java没有像脚本语言那样的很多语法糖。

1

不同的语言需要不同的风格。试图在java中完成mylist[:i] + mylist[i+1:]就像使用带螺丝的锤子。是的,你可以做到,但不是很整齐。我相信可能是类似的东西ArrayList temp = new ArrayList(list); temp.remove(index);

我相信以下完成相同的任务,但以稍微不同的方式,但不会遭受可读性问题。它不是创建一个新列表,而是修改列表并将其传递,并在递归调用返回时将列表返回到其先前的状态。

import java.util.Arrays; 
import java.util.List; 
import java.util.ArrayList; 

public class Permutation { 

    public static void main(String[] args) { 

     List<List<Integer>> result = permutations(
             Arrays.asList( 
              new Integer[] {1,2,3})); 

     for (List<Integer> permutation : result) { 
     System.out.println(permutation); 
     } 
    } 


    public static <T> List<List<T>> permutations(List<T> input) { 
     List<List<T>> out = new ArrayList<List<T>>(); 
     permutationsSlave(input, new ArrayList<T>(), out); 
     return out; 
    } 

    public static <T> void permutationsSlave(List<T> input, 
      ArrayList<T> permutation, List<List<T>> result) { 

     if (input.size() == chosen.size()) { 
     result.add(new ArrayList<T>(permutation)); 
     return; 
     } 

     for (T obj : input) { 
     if (!permutation.contains(obj)) { 
      permutation.add(obj); 
      permutationsSlave(input, permutation, result); 
      permutation.remove(permutation.size()-1); 
     } 
     } 

    } 
} 

Python是这样可以看起来很容易和更清洁的,但看起来干净能力往往隐藏的事实,解决的办法是非常低效的(递归的每一层它创建5个新的列表)。

但是然后我自己的解决方案不是非常高效 - 而不是创建多个新对象它执行冗余比较(尽管其中一些可以通过使用累加器来缓解)。

相关问题