等量置换java_Java:寻找置换算法

假设我有一个数组.

String[] arr = {"a", "b", "c"};

我需要获取所有可能的组合,例如:

a

a b

a c

a b c

a c b

b

b a

b c

b a c

b c a

c

c a

c b

c a b

c b a

我应该使用哪种快速算法来获得所有组合?

UPD

public static void permute(List done, List remaining {

remaining.removeAll(Collections.singletonList(null));

done.removeAll(Collections.singletonList(null));

System.out.println(done);

if (remaining.size() == 0) {

return;

}

for (int i = 0; i < remaining.size(); i++) {

Integer e = remaining.get(i);

done.add(e);

remaining.set(i, null);

permute(done, remaining);

remaining.add(e);

done.set(i, null);

}

}

输出量

[]

[1]

[1, 2]

[1, 2, 3]

[1, 2, 3, 4]

[2, 3, 4, 3]

[2, 3, 4, 3, 4]

[4, 3, 4, 3]

[4, 3, 4, 3, 4]

[4, 3, 4, 3, 4, 2]

[3, 4, 3, 4, 2, 4]

[3, 4, 3, 4, 2, 4, 2]

[3, 4, 2, 4, 2, 3]

[3, 4, 2, 4, 2, 3, 2]

[3, 4, 2, 4, 2, 3, 2, 4]

[4, 2, 4, 2, 3, 2, 4, 2]

[4, 2, 4, 2, 3, 2, 4, 2, 4]

[2, 3, 2, 4, 2, 4, 2]

[2, 3, 2, 4, 2, 4, 2, 4]

[2, 3, 2, 4, 2, 4, 2, 4, 3]

[2, 3, 2, 4, 2, 4, 2, 4, 3, 1]

[3, 2, 4, 2, 4, 2, 4, 3, 1, 3]

[3, 2, 4, 2, 4, 2, 4, 3, 1, 3, 1]

[4, 2, 4, 2, 4, 3, 1, 3, 1, 3]

[4, 2, 4, 2, 4, 3, 1, 3, 1, 3, 1]

[4, 2, 4, 2, 4, 3, 1, 3, 1, 3, 1, 4]

[2, 4, 2, 4, 3, 1, 3, 1, 3, 1, 4, 1]

[2, 4, 2, 4, 3, 1, 3, 1, 3, 1, 4, 1, 4]

[2, 4, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3]

[2, 4, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3, 4]

[2, 4, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3, 4, 1]

[4, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3, 4, 1, 4]

[4, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3, 4, 1, 4, 1]

[3, 1, 3, 1, 4, 1, 4, 3, 4, 1, 4, 1, 3]

[3, 1, 3, 1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1]

[3, 1, 3, 1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4]

[3, 1, 3, 1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2]

[1, 3, 1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4]

[1, 3, 1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2]

[1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4]

[1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2]

[1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1]

[4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2]

[4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1]

[4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4]

[4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1]

[4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2]

[3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1]

[3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2]

[4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3]

[4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2]

[4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1]

[4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4]

[1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1]

[1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4]

[1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1]

[1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4]

[1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2]

[4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2, 4]

[4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2, 4, 2]

[4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2, 4, 2, 1]

[4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2, 4, 2, 1, 2]

[4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2, 4, 2, 1, 2, 4]

[2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2, 4, 2, 1, 2, 4, 2]

[2, 4

, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2, 4, 2, 1, 2, 4, 2, 4]

UPD3

我找到了一些代码,并对其进行了重新设计.所以我得到了这个:

public class Permutations {

public static void main(String[] args) {

Set combos = new Permutations().combos("1", "2", "3", "4", "5");

for (String combo : combos) {

for (char e : combo.toCharArray()){

System.out.printf("[%s]", e);

}

System.out.println();

}

}

public Set combos(String... input) {

Set set = new TreeSet<>();

combos(input, set, input.length, new StringBuffer());

return set;

}

private void combos(String[] input, Set set, int len, StringBuffer buf) {

if (len == 0) {

String elem = unique(buf.toString());

set.add(elem);

} else {

for (String t : input) {

buf.append(t);

combos(input, set, len - 1, buf);

buf.deleteCharAt(buf.length() - 1);

}

}

}

private String unique(String input) {

StringBuilder unique = new StringBuilder();

for (int i = 0; i < input.length(); i++) {

String si = input.substring(i, i + 1);

if (unique.indexOf(si) == -1)

unique.append(si);

}

return unique.toString();

}

}

工作正常.

解决方法:

普通的排列生成算法应该可以工作,您需要做的就是对其进行调整以显示排列的前缀.

我最近给了一个answer for permutations,但它在python中.应该很容易转换为Java.

这是代码,添加了前缀打印的调整:

def permute(done, remaining):

print done # Move this to the if below to print only full permutations.

if not remaining:

return

sorted_rem = sorted(remaining)

l = len(sorted_rem)

for i in xrange(0, l):

c = sorted_rem[i]

# Move to c to done portion.

done.append(c)

remaining.remove(c)

# Permute the remaining

permute(done, remaining)

# Put c back.

remaining.append(c)

# Remove from done.

del done[-1]

def main():

permute([], range(1,4))

if __name__ == "__main__":

main()

这是输出:

[]

[1]

[1, 2]

[1, 2, 3]

[1, 3]

[1, 3, 2]

[2]

[2, 1]

[2, 1, 3]

[2, 3]

[2, 3, 1]

[3]

[3, 1]

[3, 1, 2]

[3, 2]

[3, 2, 1]

这是适用于我的Java中相同的算法,似乎您的尝试存在错误(例如,从完成中删除,设置为null而不是删除).

class Permutation {

public static void print(ArrayList array) {

System.out.print("[");

for (Integer elem: array) {

System.out.print(elem.toString());

}

System.out.println("]");

}

public static void Permute(ArrayList done,

ArrayList remaining) {

print(done);

if (remaining.size() == 0) {

return;

}

ArrayList sorted = new ArrayList(remaining);

Collections.sort(sorted);

for (int j = 0; j < remaining.size(); j++) {

Integer c = sorted.get(j);

remaining.remove(c);

done.add(c);

Permute(done, remaining);

done.remove(c);

remaining.add(0, c);

}

}

public static void main(String[] args) {

ArrayList remaining =

new ArrayList(Arrays.asList(1,2,3,4));

ArrayList done = new ArrayList();

Permute(done, remaining);

}

}

标签:combinatorics,java,algorithm

来源: https://codeday.me/bug/20191120/2043601.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值