我正在逐字节地读取四个文件,并比较所有这四个字节,从这四个字节中得到一个最后一个字节。它的工作方式是:
0
,则输出0
0
,则输出奇数字节输出(如果字节为0, 0, 1, 0
,那么我将输出1
)0
,那么我随机输出一个非0
字节0
,那么我从其他3个字节输出最多的字节,否则在出现平局的情况下我从该集合输出一个随机字节0
,那么我输出最多的字节,否则在出现平局的情况下我会从该集输出一个随机字节需要注意的一点是,“随机”并不是随机的,我可以选择最方便的。
所以我已经考虑了一些,但我仍然无法想出从这些数字中获取输出的绝对最快的方法。我注意到的一件事是,如果我读取的前两个字节是相同且非零,那么我可以跳过接下来的两个字节,只输出前两个字节中的一个。如果前三个字节是0
,那么我可以输出最后一个字节。我还可以检查第一个字节和第二个字节的第三个字节,看看它们是否相等,这样我就可以避免进入第4个字节,但我需要这个字体尽可能高效。我需要在这个算法上运行大约80亿次,所以每一点都要计算=)
无论如何,最有效的方法是什么? (伪代码?或其他)
这就是程序的样子(至少它的外壳):
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class reconstructerv2 {
public static void main(String[] args) throws IOException {
FileInputStream in1 = null;
FileInputStream in2 = null;
FileInputStream in3 = null;
FileInputStream in4 = null;
FileOutputStream out = null;
try {
in1 = new FileInputStream("1.dd");
in2 = new FileInputStream("2.dd");
in3 = new FileInputStream("3.dd");
in4 = new FileInputStream("4.dd");
BufferedInputStream in1b = new BufferedInputStream(in1);
BufferedInputStream in2b = new BufferedInputStream(in2);
BufferedInputStream in3b = new BufferedInputStream(in3);
BufferedInputStream in4b = new BufferedInputStream(in4);
out = new FileOutputStream("final.dd");
int a;
int b;
int c;
int d;
int o;
while ((a = in1.read()) != -1) {
b = in2.read();
if (a == b && a != 0)
o = a;
else {
c = in3.read();
d = in4.read();
}
System.out.println((byte) c);
out.write((byte) o);
}
} finally {
if (in1 != null) {
in1.close();
in2.close();
in3.close();
in4.close();
}
if (out != null) {
out.close();
}
}
}
}
编辑:80亿,而不是800万
EDIT2:正如评论中所指出的,由于同步,我不能跳过阅读字符。
答案 0 :(得分:1)
如果所有字节都为0,则输出0
输出a + b + c + d。
如果除1字节以外的所有字节都为0,则输出奇数字节输出(如果字节为0,0,1,0,那么我将输出1)
与上述相同。这已经为您节省了一个案例。如果任何三个字节为零,则输出总和。
如果2个字节为0,则我随机输出一个非0字节 如果1个字节是0,那么我从其他3个字节输出最多的字节,否则在连接的情况下我从该组输出一个随机字节 如果所有字节都是非0,那么我输出最多出现的字节,否则在出现平局的情况下我输出该集合中的随机字节
这些案件实际上都是一样的。输出最多出现的非零字节,或者在出现平局时输出随机字节。
因此,实际上只有两种情况需要考虑:至少三个零字节,两个或更少。
事实上所有案件都是相同的。您可以将上面的第二个解决方案应用于所有案例。最好不要将它们分开。
但首先在那些FileInputStreams周围添加了BufferedInputStreams。
答案 1 :(得分:1)
这个while循环不起作用:
while ((a = in1.read()) != -1) {
b = in2.read();
if (a == b && a != 0)
o = a;
else {
c = in3.read();
d = in4.read();
}
System.out.println((byte) c);
out.write((byte) o);
}
因为有时你会读取file1和file2,有时你会读取所有四个文件。
另一点:当你读取所有四个文件时o
未设置或具有前一轮的值。如果您只读取file1和file2,这也适用于c
。因此,为了解决这个问题,总是必须读取所有四个文件,然后循环的性能并不重要。