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.