Java 两个向量之间的置换
我正在学习一些算法的技巧,但被一个问题绊住了,我需要在两组之间做一个排列。例如: [1,2,3]e[5,6,7] 需要产生: [5,2,3]e[1,6,7] [5,6,3]e[1,2,7] 等等 从这个到目前为止,我所做的是在你们之间的一个向量中进行排列 传递一个向量[1,2,3]。生成答案: 123 132 213 231 321 312 根据以下代码:Java 两个向量之间的置换,java,algorithm,Java,Algorithm,我正在学习一些算法的技巧,但被一个问题绊住了,我需要在两组之间做一个排列。例如: [1,2,3]e[5,6,7] 需要产生: [5,2,3]e[1,6,7] [5,6,3]e[1,2,7] 等等 从这个到目前为止,我所做的是在你们之间的一个向量中进行排列 传递一个向量[1,2,3]。生成答案: 123 132 213 231 321 312 根据以下代码: public void permutar(int[] num, int idx) { for (int i = idx; i &l
public void permutar(int[] num, int idx) {
for (int i = idx; i < num.length; i++) {
swap(num, i, idx);
permutar(num, idx + 1);
swap(num, i, idx);
}
if (idx == num.length - 1) {
for (int i = 0; i < num.length; i++) {
System.out.print(num[i]);
}
System.out.println("");
}
}
public void swap(int[] num, int a, int b) {
int aux = num[a];
num[a] = num[b];
num[b] = aux;
}
public void permutar(int[]num,int idx){
for(int i=idx;i
如何在这两个向量之间进行排列?如对OP问题的评论中所述,您必须生成组合。通常的用例是从集合中获取一些元素子集。在这个问题中,您需要一个子集,它表示从第一个集合中获取的元素,其余的将从第二个集合中获取 为了实现这种组合,我建议循环计数从0到2^n(其中n是一个数组中的元素数)。然后取这个数字,用二进制表示。现在,二进制表示中的每个0或1表示应该从哪个集合中给定数字(第二个集合正好相反)
我猜这是一个家庭作业或心理练习,因此代码不包括在内:您的任务等于列出6元素集的所有3元素子集。由于3元素集中的顺序无关紧要,因此应该定义一个顺序,如“较小的数字优先” 然后算法变得显而易见:list=[1 2 3 5 6 7] 编辑:Set1应始终是包含数字1的集合,以避免对称相同的解决方案 对于我从2到5的所有数字 对于从i+1到5的所有数字j Set1={list[1],list[i],list[j]} Set2=“其他数字” 这应该会让你的9元素注释中的有序列表正确无误 显然,这些都是嵌套循环。尽管您没有准确描述要查找的内容,并试图回答:看起来您只是在查找输入的所有3元素子集(1,2,3,5,6,7)。每个子集是一个解的第一个向量,其余元素是另一个向量 下面是一个基于我不久前编写的实用程序类的计算示例:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
public class CombinationsOfVectors
{
public static void main(String[] args)
{
List<Integer> input = Arrays.asList(1,2,3,5,6,7);
ChoiceIterable<Integer> c = new ChoiceIterable<Integer>(3, input);
for (List<Integer> v0 : c)
{
Set<Integer> s = new LinkedHashSet<Integer>(input);
s.removeAll(v0);
List<Integer> v1 = new ArrayList<Integer>(s);
System.out.println(v0+" and "+v1);
}
}
}
// From https://github.com/javagl/Combinatorics/blob/master/src/
// main/java/de/javagl/utils/math/combinatorics/ChoiceIterable.java
// See the GitHub repo for a commented version
class ChoiceIterable<T> implements Iterable<List<T>>
{
private final List<T> input;
private final int sampleSize;
private final long numElements;
public ChoiceIterable(int sampleSize, List<T> input)
{
this.sampleSize = sampleSize;
this.input = input;
long nf = factorial(input.size());
long kf = factorial(sampleSize);
long nmkf = factorial(input.size() - sampleSize);
long divisor = kf * nmkf;
long result = nf / divisor;
numElements = result;
}
private static long factorial(int n)
{
long f = 1;
for (long i = 2; i <= n; i++)
{
f = f * i;
}
return f;
}
@Override
public Iterator<List<T>> iterator()
{
return new Iterator<List<T>>()
{
private int current = 0;
private final int chosen[] = new int[sampleSize];
{
for (int i = 0; i < sampleSize; i++)
{
chosen[i] = i;
}
}
@Override
public boolean hasNext()
{
return current < numElements;
}
@Override
public List<T> next()
{
if (!hasNext())
{
throw new NoSuchElementException("No more elements");
}
List<T> result = new ArrayList<T>(sampleSize);
for (int i = 0; i < sampleSize; i++)
{
result.add(input.get(chosen[i]));
}
current++;
if (current < numElements)
{
increase(sampleSize - 1, input.size() - 1);
}
return result;
}
private void increase(int n, int max)
{
if (chosen[n] < max)
{
chosen[n]++;
for (int i = n + 1; i < sampleSize; i++)
{
chosen[i] = chosen[i - 1] + 1;
}
}
else
{
increase(n - 1, max - 1);
}
}
@Override
public void remove()
{
throw new UnsupportedOperationException(
"May not remove elements from a choice");
}
};
}
}
如果这不是你一直在寻找的,你应该更清楚和准确地描述预期的结果是什么
(例如,是否
[1, 2, 3] and [5, 6, 7]
及
计算不同的结果取决于您,但您可以相应地过滤结果)您可以将其作为一个向量使用,或者将它们放入一个向量中,或者由一个getter根据数字选择向量1或向量2,然后进行置换。[1,2,3]e[5,6,7]和[1,2,3,5,6,7]的置换有什么区别。你不是简单地做了6个数字的排列吗?@flaschenpost有两个想法,一个想法:-)我不能像一个向量一样使用simple,因为我不想花费计算机处理来做1,2,3之间的排列,我只能在两个向量之间进行排列。[2,1,3]和[5,6,7]不是有效的置换。如果@Marco13是正确的,您可以使用位表示。i、 e.000是指
[1,2,3]e[5,6,7]
;101表示[5,2,7]e[1,6,3]
。通过从0
到n
生成所有这些值,我不能这样做,因为一个数组中3个值的组合数不是2^3,而是更多。@NicolasBontempo:2^3没有那么大。所以,简单地列出这8个案例,告诉我们遗漏了什么。你说过[1,2,3]和[1,3,2]对你来说是相等的,所以实际上应该只有这8种情况。@flaschenpost抱歉,你是对的。只比2^3多1。[123][567][125][367][126][537][127][563][135][267][136][267][137][256][156][237][157][236][167][235]@NicolasBontempo你是对的,000-111是错的,所以Vaclav Blazej是错的。从定义运算的整个集合[1 2 3 5 6 7]中取6中的3。@flaschen是否用相等的解描述运算;)这将给我sets1[123][235][356][567]的答案,然后这将给我一个索引越界的错误。因为当i=5时,j等于6,k等于7(越界)。指数问题我有固定的对称解,避免了。但是,如果需要,您应该尝试查看嵌套循环。现在我得到了123125126127135136137156157167,所以4+3+2+1=10个解
[1, 2, 3] and [5, 6, 7]
[5, 6, 7] and [1, 2, 3]