Read in N Lines of an Input Stream and print in reverse order without using array or list type structure?

偶尔善良 提交于 2020-01-02 04:25:19

问题


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?


回答1:


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);
}



回答2:


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);



回答3:


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);
    }
}



回答4:


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);
        }
    }
}



回答5:


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.




回答6:


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());    
   }
}


来源:https://stackoverflow.com/questions/6480212/read-in-n-lines-of-an-input-stream-and-print-in-reverse-order-without-using-arra

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!