【问题标题】:Completely stumped on a Java problem完全被Java问题难住了
【发布时间】:2011-09-17 05:32:01
【问题描述】:

请注意:我不是在“寻找代码”——只是解决这个问题的算法的想法。

这是一项家庭作业。我以为我正处于最后阶段,即将完成,但最后一部分绝对让我难过。我从来没有被这样困住过。它与 Java 中的线程有关。

Driver 类读取文件,第一行表示线程数,第二行是每个线程要读取的文件名的空格分隔列表。每个线程都有编号(0 - N),N 是文件的总数。每个线程读取指定的文件,并输出到名为 t#_out.txt 的文件,其中 # 是线程索引。

完成所有这些后,驱动线程必须:

所有线程执行完毕后,Driver.java程序打开所有线程 输出文件 t#_out.txt,从每个文件中读取一行,然后写入 到输出文件 out.txt 的行。

out.txt 示例:

MyThread[0]: Line[1]: 有些东西不喜欢墙,
MyThread[1]: Line[1]: HOG Butcher for the World,
MyThread[2]: Line[1]: 我想我永远看不到
MyThread[0]: Line[2]: 在它下面发送冻结的地面膨胀,
MyThread[1]: Line[2]: Tool Maker, Stacker of Wheat,
MyThread[2]: Line[2]: 一首像树一样可爱的诗。
MyThread[0]: Line[3]: 把上面的巨石洒在阳光下,
MyThread[1]: Line[3]: 铁路玩家和国家货运经理;
MyThread[2]: Line[3]: 一棵树,嘴巴很饿

我的问题是:我可以设置什么样的循环结构来做到这一点?从 t1_out.txt 读取一行,写入 out.txt,从 t2_out.txt 读取一行,写入 out.txt,从 tN_out.txt 读取一行,写入 out.txt?我如何知道一个文件何时结束?

想法:

  1. 使用 while(!done) 循环继续循环,直到完成每个扫描程序。跟踪一个布尔数组,指示扫描器是否已完成读取其文件。扫描仪也将在一个数组中。问题是我如何判断所有内容何时完成,以完成我的无限循环?在每次迭代中查看 booleans[i] 是否完成,如果没有完成 = false?不好。

  2. 只需将每个文件行读入其自己的 String[] 数组即可。然后找出一个循环来交替写入 out.txt。问题是当我超出数组索引时会发生什么?这也不在规范中,它说读一行,写一行。

编辑:解决方案是创建一个 allFilesReachedEOF() 方法,该方法的初始布尔值为 true。然后它循环遍历每一个,如果 ANY 有另一行要读取,则将返回条件设置为 false。这是我的 while 循环条件:while (!allFilesReachedEOF())。

我的问题是我试图从循环内控制循环。因此,如果一个文件有另一行,它将继续,但如果任何文件 EOF'd,循环将停止。

感谢您的帮助!

【问题讨论】:

    标签: java arrays algorithm java.util.scanner


    【解决方案1】:

    您可以在并非所有文件都达到 EOF 的情况下做一段时间。然后您遍历所有文件,对于那些尚未达到 EOF 的文件,您读取下一行并将其写入您的输出文件。随着您的进行,您会更新“while”循环的条件变量。

    这是你想要做的吗?

    【讨论】:

    • 你知道吗 - 这与我尝试做的类似,但我的问题是我的 eofReached 标志为假。如果我将此检查放入一个方法中,并最初将其设置为 TRUE,然后循环每个扫描仪以查看它是否 .hasNext(),这可能会起作用。我会尽快更新你。
    • 酷,告诉我进展如何。
    • 做到了——这是我试图从循环中设置的初始标志。谢谢!
    【解决方案2】:

    听起来您可以使用Queue 来实现这一点。将每个 t#_out.txt 的输入添加到 Queue 然后实现一个循环,在该循环中您从轮询输入中读取一行并将其写入您的输出。只要读取的行不是 EOF,就将输入重新添加到Queue。当Queue 为空时,跳出循环。

    另外我推荐一个BufferedWriter作为输出,你在最后flush()这样实际的写入只发生一次。

    【讨论】:

    • 感谢您的建议,虽然我可能会走这条路,但现在是凌晨 1 点 17 分,我累了 :)。
    【解决方案3】:

    以下是要点:

    • 创建一个实现Runnable 的类,其run() 方法可以完成您需要一个线程执行的操作。它可能需要threadNumberfilename 的字段。 run 方法应该确保 close() 输出文件的输出流
    • 对于您需要创建的每个线程,实例化您的一个类(为其提供所需的文件名(和其他)数据)并将其传递到constructor of Thread。保留对 Thread 对象的引用
    • 在所有线程上调用start()方法
    • 在所有线程上调用join()方法(join等待线程完成)
    • 执行最后的驱动程序任务,打开输出文件

    【讨论】:

    • 前4点我已经做了,我的问题是最后一个。
    • 在所有的 join() 方法都返回(这是一个阻塞调用)之后,所有线程都已完成并且您的输出文件已准备好读取
    • @Bohemian - 我不认为多线程是这里的问题。 OP 正在询问一次读取每个 `t#_out.txt` 一行(循环)并将所有内容写入out.txt 的(同步)任务。
    【解决方案4】:

    这可以通过使用 do - while “退出条件”循环和用于迭代输出文件的内部 for 循环来完成。在 for 循环开始之前将退出条件设置为 true,如果从任何文件中至少获得一行,则在 for 循环中将其重置。

    已达到 eof 的文件将继续被读取,但不会返回任何行。您可以选择为这些打印空白行或跳过它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-06
      • 2012-08-13
      • 2018-04-20
      • 2012-02-19
      • 1970-01-01
      • 2013-10-31
      • 1970-01-01
      相关资源
      最近更新 更多