简体   繁体   中英

Convert matlab to java

i am new in java programming.I need to convert my matlab code to basic java codes not complex like just using loops and array, i tried several times but i failed.Thanks for helping.Here is my code.

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

Let us go through the Matlab code and translate each row into Java. We will be going to need some abstractions, which we will introduce on the go.

First line:

x = [1,2,3,4,5,6,7]; 

A vector is assigned to a variable x . We could simply say that a vector is an array of integers, but maybe we need some better abstractions later. Let us define a new class Vector . Do not confuse it with java.util.Vector : There may be multiple classes of the same unqualified name.

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();
    }
}

We are using an array of integers for the internal representation of our Vector . Note that you can swap out the internal representation any time as long as it does not leak out into the classe's interface. Hence, we restrict the access of our value -member to private , meaning only objects of type Vector are allowed to access it.

New Vector objects are instantiated by calling the constructor Vector(int... value) , which takes a vararg integer argument. Internally in Java, varargs are the same as arrays, but they give us syntactic sugar, to instantiate our x in the following way:

Vector x = new Vector(1, 2, 3, 4, 5, 6, 7); 

which looks very similar to your Matlab code.

An other thing is that, in Java, arrays are zero-indexed, while Matlab starts indexing at 1. Our Vector class defines an apply -method, which is supposed to access the i -th index. Hence, it returns value[i-1] .

Now we want to compute

x = perms(x);

perms returns a matrix, containing all permutations of vector x . So we need an other abstraction: 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 is defined very similar to Vector , but its internal representation is an array of Vector , the rows of the matrix. Again, we define a method apply to retrieve an element: this time, it takes two parameters, the row index and the column index.

Side note: It is always good to override the method toString which is defined in the top element of Java's type hierarchy: Object . You can try to instantiate a Vector or a Matrix and pass it as argument to System.out.println to see how the string representation looks like.

Now we still need to implement perms in Java. The method perms takes a Vector and returns a Matrix . I have a very hacked and ugly implementation which I am a bit reluctant to show, but for the sake of a complete answer, here it is:

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);
        }
    }
}

Don't bother to understand what it is doing. Try writing a clean implementation on your own (or google for a solution).

Now, if we want to reassign our x , we run into trouble: The type does not match: We declared x to be of type Vector , but perm is returning a Matrix . There are multiple ways to solve this:

  • We could declare Vector to be a Matrix , ie, change the signature to Vector extends Matrix . This solution may make sense, but be careful not to break behavioral subtyping: If a class B is a class A , then B must have the same behavior as A and can define additional behavior. Look up the Liskov Substitution Principle on the same note.

  • We could declare x to be of a supertype of both, Vector and Matrix . Currently, this is Object , but we could also define a new common supertype. This solution may however lose our static type safety. For example, if we want to use x as argument to perm , we need to dynamically cast it to a Vector

  • We could define a second variable x2 of type Matrix which holds the result. I suggest this solution in this case.

Next, we assign i = 0; and c=1; , which in Java translates to

int i = 0; 
int c = 1; 

Now, the for-loops:

for m = 1:1:5040
    ...
end

translates to

for (int m = 1; m <= 5040; i++) {
    ...
}

The only thing remaining, besides putting it all together, is the if-statement:

if(x2(c,n) == (x2(c,(n+1))-1))
    ...
end

translates to

if (x2.apply(c, n) == (x2.apply(c, n+1) - 1)) {
    ...
}

where apply is the method we defined on Matrix . Note that in Java, == will give you strange results if applied to non-primitive types, ie, everything besides int , byte , char , double , boolean , and float . Generally, you test equivalence using the method equals which is defined on Object .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM