使用hasNext()方法时最后一个Token未被处理的问题求解
合并两个已排序文件时的最后元素处理问题
问题描述
尝试将两个已排序文件(fn1 和 fn2)合并为第三个已排序文件(fn3),但使用while循环遍历文件时遇到问题:当hasNext()方法到达文件的最后一个数字时,由于后续没有下一个数字导致hasNext()返回false,循环会退出而不处理该最后一个数字。
测试文件内容:
- 文件1:
5 16 47 - 文件2:
12 21 67
当前使用的Java代码:
int x, y; x = fn1.nextInt(); // 从文件F1读取x y = fn2.nextInt(); // 从文件F2读取y while (fn1.hasNext() && fn2.hasNext()) { if (x <= y) { fn3.printf("%3d ", x); // 将x写入文件F3 x = fn1.nextInt(); // 从文件F1读取下一个x } // end if else { fn3.printf("%3d ", y); // 将y写入文件F3 y = fn2.nextInt(); // 从文件F2读取下一个y } // end else } // end while
参考教授提供的伪代码(已翻译为中文):
// 打开输入文件F1、F2 openinput(F1); openinput(F2); // 打开输出文件F3 openoutput(F3); // 从文件F1读取x x = readinput(F1); // 从文件F2读取y y = readinput(F2); // eof代表文件结束 while (!eof(F1) && ! eof(F2)) If ( x ≤ y) { // 将x写入文件F3 write(F3, x); // 从文件F1读取下一个x x = readinput(F1); } // end if else{ // 将y写入文件F3 write(F3, y); // 从文件F2读取下一个y y = readinput(F2); } // end else // endwhile // 将F2中未处理的数据追加到F3 If (eof(F1)) ......... // 将F1中未处理的数据追加到F3 If (eof(F2)) ......... 关闭所有I/O文件。 // end pseudo code
问题原因
原代码的循环条件fn1.hasNext() && fn2.hasNext()会在其中一个文件读完最后一个元素的下一个位置时退出循环,但此时已经读取的x或y还没有被写入fn3,同时其中一个文件可能还有剩余元素未处理。
解决方法
按照教授伪代码的思路,在主循环结束后,需要额外处理剩余的元素:
- 先处理主循环中未写入的
x和y的比较逻辑; - 再遍历其中一个文件剩余的所有元素,全部写入
fn3。
修正后的完整Java代码:
int x, y; // 初始化读取第一个元素 x = fn1.nextInt(); y = fn2.nextInt(); // 主循环:当两个文件都还有下一个元素时执行 while (fn1.hasNext() && fn2.hasNext()) { if (x <= y) { fn3.printf("%3d ", x); x = fn1.nextInt(); } else { fn3.printf("%3d ", y); y = fn2.nextInt(); } } // 处理最后一轮未写入的元素及剩余内容 if (x <= y) { fn3.printf("%3d ", x); // 写入fn1剩余的所有元素 while (fn1.hasNext()) { fn3.printf("%3d ", fn1.nextInt()); } // 写入y以及fn2剩余的所有元素 fn3.printf("%3d ", y); while (fn2.hasNext()) { fn3.printf("%3d ", fn2.nextInt()); } } else { fn3.printf("%3d ", y); // 写入fn2剩余的所有元素 while (fn2.hasNext()) { fn3.printf("%3d ", fn2.nextInt()); } // 写入x以及fn1剩余的所有元素 fn3.printf("%3d ", x); while (fn1.hasNext()) { fn3.printf("%3d ", fn1.nextInt()); } } // 实际代码中建议使用try-with-resources自动关闭流,此处仅示意 fn1.close(); fn2.close(); fn3.close();
简化处理方案
也可以简化剩余元素的处理逻辑,先写完当前的x和y,再分别检查两个文件是否有剩余元素并逐个写入:
// 主循环结束后 // 先处理当前的x和y if (x <= y) { fn3.printf("%3d ", x); fn3.printf("%3d ", y); } else { fn3.printf("%3d ", y); fn3.printf("%3d ", x); } // 写入fn1剩余元素 while (fn1.hasNext()) { fn3.printf("%3d ", fn1.nextInt()); } // 写入fn2剩余元素 while (fn2.hasNext()) { fn3.printf("%3d ", fn2.nextInt()); }
若其中一个文件已无剩余元素,对应的循环会自动跳过,不影响最终结果。
内容的提问来源于stack exchange,提问作者Gio3211
相关产品推荐
相关产品推荐

