You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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,同时其中一个文件可能还有剩余元素未处理。

解决方法

按照教授伪代码的思路,在主循环结束后,需要额外处理剩余的元素:

  1. 先处理主循环中未写入的x和y的比较逻辑;
  2. 再遍历其中一个文件剩余的所有元素,全部写入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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 14:05:35