我有一个包含二维矩阵的文本文件。它看起来像下面这样。
01 02 03 04 05
06 07 08 09 10
11 12 13 14 15
16 17 18 19 20
如您所见,每行由换行符分隔,每列由空格分隔。我需要以有效的方式转置这个矩阵。
01 06 11 16
02 07 12 17
03 08 04 05
04 09 14 19
05 10 15 20
实际上,矩阵是 10,000 x 14,000。各个元素是 double /浮点型。尝试将这个文件/矩阵全部转置在内存中,即使不是不可能,也是昂贵的。
有谁知道 util API 可以做这样的事情或有效的方法吗?
我尝试过的:我天真的方法是为(转置矩阵的)每一列创建一个临时文件。因此,如果有 10,000 行,我将有 10,000 个临时文件。当我读取每一行时,我会标记每个值,并将该值附加到相应的文件中。因此,通过上面的示例,我将得到如下所示的内容。
file-0: 01 06 11 16
file-1: 02 07 12 17
file-3: 03 08 13 18
file-4: 04 09 14 19
file-5: 05 10 15 20
然后我读回每个文件并将它们附加到一个文件中。我想知道是否有更聪明的方法,因为我知道文件 I/O 操作将是一个痛点。
最佳答案
具有最小内存消耗和极低性能的解决方案:
import org.apache.commons.io.FileUtils;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class MatrixTransposer {
private static final String TMP_DIR = System.getProperty("java.io.tmpdir") + "/";
private static final String EXTENSION = ".matrix.tmp.result";
private final String original;
private final String dst;
public MatrixTransposer(String original, String dst) {
this.original = original;
this.dst = dst;
}
public void transpose() throws IOException {
deleteTempFiles();
int max = 0;
FileReader fileReader = null;
BufferedReader reader = null;
try {
fileReader = new FileReader(original);
reader = new BufferedReader(fileReader);
String row;
while((row = reader.readLine()) != null) {
max = appendRow(max, row, 0);
}
} finally {
if (null != reader) reader.close();
if (null != fileReader) fileReader.close();
}
mergeResultingRows(max);
}
private void deleteTempFiles() {
for (String tmp : new File(TMP_DIR).list()) {
if (tmp.endsWith(EXTENSION)) {
FileUtils.deleteQuietly(new File(TMP_DIR + "/" + tmp));
}
}
}
private void mergeResultingRows(int max) throws IOException {
FileUtils.deleteQuietly(new File(dst));
FileWriter writer = null;
BufferedWriter out = null;
try {
writer = new FileWriter(new File(dst), true);
out = new BufferedWriter(writer);
for (int i = 0; i <= max; i++) {
out.write(FileUtils.readFileToString(new File(TMP_DIR + i + EXTENSION)) + "\r\n");
}
} finally {
if (null != out) out.close();
if (null != writer) writer.close();
}
}
private int appendRow(int max, String row, int i) throws IOException {
for (String element : row.split(" ")) {
FileWriter writer = null;
BufferedWriter out = null;
try {
writer = new FileWriter(TMP_DIR + i + EXTENSION, true);
out = new BufferedWriter(writer);
out.write(columnPrefix(i) + element);
} finally {
if (null != out) out.close();
if (null != writer) writer.close();
}
max = Math.max(i++, max);
}
return max;
}
private String columnPrefix(int i) {
return (0 == i ? "" : " ");
}
public static void main(String[] args) throws IOException {
new MatrixTransposer("c:/temp/mt/original.txt", "c:/temp/mt/transposed.txt").transpose();
}
}
关于java - 在文本文件中转置矩阵的有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9782939/