读取输入流的 N 行并以相反的顺序打印而不使用数组或列表类型结构?

发布于 2024-11-17 01:54:04 字数 75 浏览 3 评论 0原文

使用 BufferedReader 的 readLine() 方法,可以在不使用列表或数组的情况下以相反的顺序打印流的前 N ​​行吗?

Using the readLine() method of BufferedReader, can you print the first N lines of a stream in reverse order without using a list or an array?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

长梦不多时 2024-11-24 01:54:04

我认为你可以通过递归来做到这一点,例如:

void printReversed(int n)
{
   String line = reader.readLine();

   if (n > 0)
     printReversed(n-1);

   System.out.println(line);
}

I think you can do it through recursion with something like:

void printReversed(int n)
{
   String line = reader.readLine();

   if (n > 0)
     printReversed(n-1);

   System.out.println(line);
}
梦途 2024-11-24 01:54:04

这里你有另一种选择,基于 BufferedReader & StringBuilder 操作。就所需的计算机资源而言更易于管理。

public void reversePrint(BufferedReader bufReader, int lines) throws IOException {
    BufferedReader resultBufferReader = null;
    {
        String line;
        StringBuilder sb = new StringBuilder();
        int count = 0;
        while (count++<lines && (line = bufReader.readLine())!=null) {
            sb.append('\n'); // restore new line marker for BufferedReader to consume.
            sb.append(new StringBuilder(line).reverse());
        }
        resultBufferReader = new BufferedReader(new StringReader(sb.reverse().toString()));
    }
    {           
        String line;
        while ((line = resultBufferReader.readLine())!=null) {
            System.out.println(line);
        }
    }
}

Here you have another alternative, based on BufferedReader & StringBuilder manipulations. More manageable in terms of computer resources needed.

public void reversePrint(BufferedReader bufReader, int lines) throws IOException {
    BufferedReader resultBufferReader = null;
    {
        String line;
        StringBuilder sb = new StringBuilder();
        int count = 0;
        while (count++<lines && (line = bufReader.readLine())!=null) {
            sb.append('\n'); // restore new line marker for BufferedReader to consume.
            sb.append(new StringBuilder(line).reverse());
        }
        resultBufferReader = new BufferedReader(new StringReader(sb.reverse().toString()));
    }
    {           
        String line;
        while ((line = resultBufferReader.readLine())!=null) {
            System.out.println(line);
        }
    }
}
贱贱哒 2024-11-24 01:54:04

怎样用递归来颠倒顺序呢?

伪代码:

reverse(int linesLeft)
   if (linesLeft == 0)
      return;
   String line = readLine();
   reverse(linesLeft - 1);
   System.out.println(line);

How about recursion to reverse the order?

Pseudo code:

reverse(int linesLeft)
   if (linesLeft == 0)
      return;
   String line = readLine();
   reverse(linesLeft - 1);
   System.out.println(line);
妖妓 2024-11-24 01:54:04

好问题。这里您有一种基于协调线程的解决方案。尽管它占用大量资源(1 个线程/缓冲区行),但它可以在给定的限制内解决您的问题。我很好奇看到其他解决方案。

public class ReversedBufferPrinter {

    class Worker implements Runnable {
           private final CountDownLatch trigger;
           private final CountDownLatch release;
           private final String  line;

           Worker(String line, CountDownLatch release) {
              this.trigger = new CountDownLatch(1);
              this.release = release;
              this.line = line;
           }

           public CountDownLatch getTriggerLatch() {
               return trigger;
           }

           public void run() {
              try {
                  trigger.await();
              } catch (InterruptedException ex) { } // handle 
              work();
              release.countDown();  
           }

           void work() { 
               System.out.println(line);
           }
    } 

    public void reversePrint(BufferedReader reader, int lines) throws IOException {
        CountDownLatch initialLatch = new CountDownLatch(1);
        CountDownLatch triggerLatch = initialLatch; 
        int count=0;
        String line;
        while (count++<lines && (line = reader.readLine())!=null) {
            Worker worker = new Worker(line, triggerLatch);
            triggerLatch = worker.getTriggerLatch();
            new Thread(worker).start();
        }
        triggerLatch.countDown();
        try {
            initialLatch.await();
        } catch (InterruptedException iex) {
            // handle
        }
    }

    public static void main(String [] params) throws Exception {
        if (params.length<2) { 
            System.out.println("usage: ReversedBufferPrinter <file to reverse> <#lines>");
        }
        String filename = params[0];
        int lines = Integer.parseInt(params[1]);
        File file = new File(filename);
        BufferedReader reader = new BufferedReader(new FileReader(file));
        ReversedBufferPrinter printer = new ReversedBufferPrinter();
        printer.reversePrint(reader, lines);
    }
}

Nice question. Here you have one solution based on coordinated threads. Although it's heavy on resources (1 thread/line of the buffer) it solves your problem within the given constrains. I'm curious to see other solutions.

public class ReversedBufferPrinter {

    class Worker implements Runnable {
           private final CountDownLatch trigger;
           private final CountDownLatch release;
           private final String  line;

           Worker(String line, CountDownLatch release) {
              this.trigger = new CountDownLatch(1);
              this.release = release;
              this.line = line;
           }

           public CountDownLatch getTriggerLatch() {
               return trigger;
           }

           public void run() {
              try {
                  trigger.await();
              } catch (InterruptedException ex) { } // handle 
              work();
              release.countDown();  
           }

           void work() { 
               System.out.println(line);
           }
    } 

    public void reversePrint(BufferedReader reader, int lines) throws IOException {
        CountDownLatch initialLatch = new CountDownLatch(1);
        CountDownLatch triggerLatch = initialLatch; 
        int count=0;
        String line;
        while (count++<lines && (line = reader.readLine())!=null) {
            Worker worker = new Worker(line, triggerLatch);
            triggerLatch = worker.getTriggerLatch();
            new Thread(worker).start();
        }
        triggerLatch.countDown();
        try {
            initialLatch.await();
        } catch (InterruptedException iex) {
            // handle
        }
    }

    public static void main(String [] params) throws Exception {
        if (params.length<2) { 
            System.out.println("usage: ReversedBufferPrinter <file to reverse> <#lines>");
        }
        String filename = params[0];
        int lines = Integer.parseInt(params[1]);
        File file = new File(filename);
        BufferedReader reader = new BufferedReader(new FileReader(file));
        ReversedBufferPrinter printer = new ReversedBufferPrinter();
        printer.reversePrint(reader, lines);
    }
}
鯉魚旗 2024-11-24 01:54:04

它还需要隐式数据结构,但您可以生成线程,按顺序运行它们,并使每个线程读取一行并等待较短的时间。结果将是:最后一个线程将首先运行,第一个线程将最后运行,每个线程都打印其行。 (它们之间的间隔必须足够大,以确保大的“安全裕度”)

我不知道如何(如果有的话)在没有显式/隐式数据存储的情况下完成这一点。

it will also require implicit data structures, but you can spawn threads, run them inorder, and make each thread read a line and wait a decreasing amount of time. the result will be: the last thread will run first, and the first one will run last, each one printing its line. (the interval between them will have to be large enough to ensure large "safety margins")

I have no idea how, if any, that can be done with no explicit/implicit data storage.

感受沵的脚步 2024-11-24 01:54:04

将您读取的每一行添加到一个字符串中,然后打印该字符串。如果您读完了所有行,只需打印您所拥有的内容即可。

或者,如果您确定拥有的行数,并且不希望使用字符串:

void printReversed(int n, BufferedReader reader)
{
   LineNumberReader lineReader = new LineNumberReader(reader);

   while (--i >= 0)
   {
      lineReader.setLineNumber(i); 
      System.out.println(lineReader.readLine());    
   }
}

Prepend each line you read to a string, and print the string. If you run out of lines to read, you just print what you have.

Alternatively, if you are certain of the number of lines you have, and you do not wish to use a string:

void printReversed(int n, BufferedReader reader)
{
   LineNumberReader lineReader = new LineNumberReader(reader);

   while (--i >= 0)
   {
      lineReader.setLineNumber(i); 
      System.out.println(lineReader.readLine());    
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文