开发者

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

开发者 https://www.devze.com 2023-03-15 15:42 出处:网络
Using the readLine() method of B开发者_如何学PythonufferedReader, can you print the first N lines of a stream in reverse order without using a list or an array?I think you can do it through recursion

Using the readLine() method of B开发者_如何学PythonufferedReader, can you print the first N lines of a stream in reverse order without using a list or an array?


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


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


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


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


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.


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

精彩评论

暂无评论...
验证码 换一张
取 消