【问题标题】:Convert matlab to java将matlab转换为java
【发布时间】:2014-10-08 20:28:43
【问题描述】:

我是 java 编程新手。我需要将我的 matlab 代码转换为基本的 java 代码,而不是像使用循环和数组那样复杂,我尝试了几次但我失败了。谢谢你的帮助。这是我的代码。

x = [1,2,3,4,5,6,7];
x = perms(x);
i = 0;
c=1;
for m=1:1:5040;
for n=1:1:6;
if(x(c,n) == (x(c,(n+1))-1))
i = i+1;
break
end 
end
c=c+1;
end

Answer : 2119

【问题讨论】:

  • i tried several times but i failed 什么你试过了吗? 什么不起作用? 什么你预计会发生什么? 会发生什么?请发布您的代码。
  • 您有 MATLAB Builder JA (mathworks.co.uk/products/javabuilder) 吗?除非您手动将 MATLAB 代码翻译成 Java,否则这就是您所需要的。
  • 不,我没有 MATLAB Builder JA,我无法将 MATLAB 代码翻译成 Java,我是 java 新手。
  • 您必须将 Matlab 代码翻译成 Java 的原因是什么?它应该是 Java 编程的练习,还是您通常想将 Matlab 翻译成 Java(例如,出于性能原因)?
  • 我正在大学学习“算法和复杂性”。这是一个我需要转换为 java 的问题。

标签: java matlab


【解决方案1】:

让我们浏览一下 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-member 的访问权限限制为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-th 索引.因此,它返回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。您可以尝试实例化 VectorMatrix 并将其作为参数传递给 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 声明为VectorMatrix 的超类型。目前,这是Object,但我们也可以定义一个新的通用超类型。然而,这个解决方案可能会失去我们的静态类型安全性。例如,如果我们想使用x 作为perm 的参数,我们需要将其动态转换为Vector

  • 我们可以定义第二个变量x2 类型为Matrix 来保存结果。在这种情况下,我建议使用此解决方案。

接下来,我们分配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++) {
    ...
}

除了把它们放在一起之外,唯一剩下的就是 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 中,如果将 == 应用于非原始类型(即,除了 intbytechardoublebooleanfloat 之外的所有内容,则会给出奇怪的结果。通常,您使用在Object 上定义的方法equals 来测试等价性。

【讨论】:

  • 非常感谢@Kulu Limpa。这很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-05
  • 2020-02-15
  • 2020-06-04
  • 1970-01-01
  • 1970-01-01
  • 2015-01-18
相关资源
最近更新 更多