是否可以在Java中进行M * N矩阵的就地矩阵转置?我不认为在Java中是可能的,因为在3 * 5矩阵中,3 * 5处的元素理想地与5 * 3处的元素交换,但是这样的位置不存在。比方说,C / C ++,因为内存是连续的,所以是可能的。
此外,还有其他算法,例如发布了here的M * N矩阵,我认为这些算法不适用于Java,但是它与A [i] [j]中交换元素的方式有何不同A [j] [i]因为即使上面链接中的滚动窗口算法也需要辅助存储器?
答案 0 :(得分:2)
您必须小心使用该术语。严格来说,转置运算符会创建'具有潜在新维度的新矩阵。对于您链接的文章,就地就意味着对初始矩阵和最终矩阵使用相同的内存,这当然可以通过巧妙的表示来实现。
一个简单的解决方案可能是:
public class Matrix {
private int[][] backingArray;
private boolean transposed;
public Matrix(int[][] _backingArray) {
this.backingArray = _backingArray
}
public Matrix(int[] data, rows, columns) {
backingArray = new int[rows][columns]
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
backingArray[i][j] = data[i*columns + j]
}
public int getElement(i, j) {
if (transposed)
return backingArray[j][i];
return backingArray[i][j];
}
public void transpose() {
transpose = !transpose;
}
}
编辑:更正了一些错误的语法
编辑:这样可以根据OP问题读入1-D矩阵(?)
答案 1 :(得分:1)
如果不指定更多的上下文,你的问题并没有太多意义:算法假定数据的线性表示(因为C [++]之类的语言基本上直接访问内存,这是有意义的在那些情况下)。请注意,对于此类表示,您需要在数据外部表示行数和列数。因此,3x4矩阵的数据表示同样可以用于4x3(或2x6等)矩阵,您只需要numberCols
和numberRows
(伪代码)中的不同值。所以这里的转置算法使用相同的内存分配,但重新排序元素并重新解释行数和列数。
如果您将Java中的(整数)矩阵表示为int[][]
,那么您不能使用相同的算法,或实际上任何就地转置,因为行和列的数量对于该特定是固定的表示:Java中的数组不可调整大小。该算法不适用,因为数据表示方式不是相同的线性。
但是如果您选择使用单维数组表示矩阵:
public class IntMatrix {
private final int numColumns ;
private final int numRows ;
private final int[] data ;
public IntMatrix(int numColumns, int numRows, int... data) {
if (data.length != numColumns*numRows) {
throw new IllegalArgumentException("...");
}
this.numColumns = numColumns ;
this.numRows = numRows ;
this.data = new data[numColumns * numRows] ;
System.arrayCopy(data, 0, this.data, 0, this.data.length);
}
public int getElement(int row, int column) {
return data[column*numRows+row];
}
public int getNumRows() {
return numRows ;
}
public int getNumColumns() {
return numColumns ;
}
}
那么你当然可以使用完全相同的算法实现就地转置。
然而,你几乎肯定不会:你会做以下事情:
public class IntMatrix {
// code as before...
public IntMatrix transpose() {
return new Transpose(this);
}
private static class Transpose extends IntMatrix {
private IntMatrix original ;
Transpose(IntMatrix original) {
this.original = original ;
}
@Override
public int getElement(int row, int column) {
return original.getElement(column, row) ;
}
@Override
public IntMatrix transpose() {
return original ;
}
@Override
public int getNumRows() {
return original.getNumColumns();
}
@Override
public int getNumColumns() {
return original.getNumRows();
}
}
}
(对于此不可变表示)创建具有O(1)操作和O(1)附加内存的转置。您可以类似地创建可变表示,只需要更多的工作,并且可能更高的成本,具体取决于您想要的确切行为(转置原始可变矩阵的视图等)。
答案 2 :(得分:0)
你是对的,它不可以。在Java中,一旦创建了一个数组,它的长度就固定了。所以,如果M和N不同,你就不能交换它们