让我们通过Matlab代码并将每行转换为Java。我们将需要一些抽象,我们将在旅途中介绍这些抽象。
第一行:
x = [1,2,3,4,5,6,7];
的载体被分配给一个变量x
。我们可以简单地说矢量是一个整数数组,但也许我们稍后需要一些更好的抽象。让我们定义一个新类Vector
。不要将它与java.util.Vector
混淆:可能有多个相同的非限定名称的类。
class Vector {
private int[] value;
Vector(int... value) {
this.value = value;
}
int apply(int i) {
return value[i - 1];
}
int length() {
return value.length;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
String prefix = "";
for (int entry : value) {
result.append(prefix).append(entry);
prefix = " ";
}
return result.toString();
}
}
我们使用整数数组作为Vector
的内部表示。请注意,只要不泄漏到类的界面中,您可以随时换出内部表示。因此,我们将我们的value
成员的访问权限限制为private
,这意味着只允许Vector
类型的对象访问它。
新建Vector
对象通过调用构造函数Vector(int... value)
来实例化,该构造函数采用可变参数整型参数。内部在Java中,可变参数是相同的阵列,但他们给我们的语法糖,来实例化x
以下列方式:
Vector x = new Vector(1, 2, 3, 4, 5, 6, 7);
看起来非常相似,你的Matlab代码。
另一件事是,在Java中,数组是零索引的,而Matlab开始索引为1.我们的Vector
类定义了一个apply
-方法,它应该访问i
的索引。因此,它返回value[i-1]
。
现在我们要计算
x = perms(x);
perms
返回一个矩阵,含有载体x
的所有排列。所以我们需要其他抽象:Matrix
。
class Matrix {
private Vector[] rows;
Matrix(Vector... value) {
this.rows = value;
}
int apply(int x, int y) {
return rows[x - 1].apply(y);
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
String prefix = "";
for (Vector row : rows) {
result.append(prefix).append(row.toString());
prefix = System.lineSeparator();
}
return result.toString();
}
}
Matrix
被定义非常类似于Vector
,但其内部表示的Vector
阵列,该矩阵的行。再次,我们定义一个方法apply
来检索一个元素:这一次,它需要两个参数,即行索引和列索引。
备注:重写方法toString
总是好的,它在Java的类型层次结构的顶层元素中定义:Object
。您可以尝试实例化Vector
或Matrix
,并将其作为参数传递给System.out.println
以查看字符串表示形式的外观。
现在我们仍然需要在Java中实现perms
。方法perms
需要Vector
并返回Matrix
。我有一个非常黑客入侵,丑陋实现这我有点舍不得显示,但对于一个完整的答案的原因,那就是:
static Matrix perms(Vector vector) {
int[] indices = new int[vector.length()];
for (int i = 0; i < vector.length(); i++)
indices[i] = i;
List<int[]> allPermuationIndices = new ArrayList<int[]>();
permutation(new int[0], indices, allPermuationIndices);
Vector[] perms = new Vector[allPermuationIndices.size()];
for (int i = 0; i < perms.length; i++) {
int[] permutationIndices = allPermuationIndices.get(i);
int[] vectorValue = new int[permutationIndices.length];
for (int j = 0; j < permutationIndices.length; j++)
vectorValue[j] = vector.apply(permutationIndices[j] + 1);
perms[i] = new Vector(vectorValue);
}
return new Matrix(perms);
}
private static void permutation(int[] prefix, int[] remaining, List<int[]> returnValue) {
if (remaining.length == 0)
returnValue.add(prefix);
else {
for (int i = 0; i < remaining.length; i++) {
int elem = remaining[i];
int[] newPrefix = Arrays.copyOf(prefix, prefix.length + 1);
newPrefix[prefix.length] = elem;
int[] newRemaining = new int[remaining.length - 1];
System.arraycopy(remaining, 0, newRemaining, 0, i);
System.arraycopy(remaining, i + 1, newRemaining, i + 1 - 1, remaining.length - (i + 1));
permutation(newPrefix, newRemaining, returnValue);
}
}
}
不要刻意去理解它在做什么。尝试自己编写一个干净的实现(或谷歌解决方案)。现在
,如果我们要重新分配我们的x
,我们遇到麻烦:类型不匹配:我们宣布x
是Vector
类型,但perm
返回一个Matrix
。有多种方法来解决这个问题:
我们可以宣布Vector
是一个Matrix
,即签名更改为Vector extends Matrix
。此解决方案可能有意义,但请注意不要打破行为子类型:如果类B
是类A
,则B
必须具有与A
相同的行为,并且可以定义其他行为。在同一张笔记上查找Liskov Substitution Principle。
我们可以声明x
属于双方的超类型,即Vector
和Matrix
。目前,这是Object
,但我们也可以定义一个新的公共超类型。然而这个解决方案可能会失去我们的静态类型安全例如,如果我们想用x
作为参数传递给perm
,我们需要动态地将其转换为Vector
我们可以定义Matrix
类型的保存结果的第二个变量x2
。我在这种情况下建议这个解决方案。
接下来,我们分配i = 0;
和c=1;
,这在Java中转化为
int i = 0;
int c = 1;
现在,for循环:
for m = 1:1:5040
...
end
转化为
for (int m = 1; m <= 5040; i++) {
...
}
o NLY东西剩下的,除了把他们放在一起,是if语句:
if(x2(c,n) == (x2(c,(n+1))-1))
...
end
转化为
if (x2.apply(c, n) == (x2.apply(c, n+1) - 1)) {
...
}
其中apply
是我们在Matrix
定义的方法。请注意,在Java中,==
如果应用于非原始类型(即除int
,byte
,char
,double
,boolean
和float
以外的所有内容)将会给出奇怪的结果。通常,您使用在Object
上定义的方法equals
来测试等同性。
'我尝试了几次,但我失败了__你试过了吗? _什么不起作用? _你预计会发生什么? _什么发生呢?请发布您的代码。 – BackSlash 2014-10-08 20:31:20
你有MATLAB Builder JA(http://www.mathworks.co。英国/产品/ javabuilder /)?除非你手动将MATLAB代码翻译成Java,否则这就是你需要的。 – am304 2014-10-08 20:33:32
不,我没有MATLAB生成器JA,我不能将MATLAB代码翻译成Java,我是java新手。 – 2014-10-08 20:41:40