Читать N строк входного потока и печатать в обратном порядке, не используя массив или структуру типа списка? - PullRequest
5 голосов
/ 26 июня 2011

Используя readLine() метод BufferedReader, можете ли вы напечатать первые N строк потока в обратном порядке без использования списка или массива?

Ответы [ 6 ]

2 голосов
/ 26 июня 2011

Я думаю, что вы можете сделать это через рекурсию с чем-то вроде:

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

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

   System.out.println(line);
}
1 голос
/ 27 июня 2011

Здесь у вас есть другая альтернатива, основанная на манипуляциях с 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);
        }
    }
}
1 голос
/ 26 июня 2011

Хороший вопрос.Здесь у вас есть одно решение на основе скоординированных потоков.Несмотря на большой объем ресурсов (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);
    }
}
1 голос
/ 26 июня 2011

Как насчет рекурсии, чтобы отменить заказ?

Псевдокод:

reverse(int linesLeft)
   if (linesLeft == 0)
      return;
   String line = readLine();
   reverse(linesLeft - 1);
   System.out.println(line);
0 голосов
/ 03 ноября 2011

Добавьте каждую строку, которую вы прочитали, к строке и напечатайте строку. Если вам не хватает строк для чтения, вы просто печатаете то, что у вас есть.

В качестве альтернативы, если вы уверены в количестве имеющихся у вас строк и не хотите использовать строку:

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

   while (--i >= 0)
   {
      lineReader.setLineNumber(i); 
      System.out.println(lineReader.readLine());    
   }
}
0 голосов
/ 26 июня 2011

это также потребует неявных структур данных, но вы можете порождать потоки, запускать их по порядку и заставлять каждый поток читать строку и ждать уменьшающееся количество времени.результат будет следующим: последний поток будет выполняться первым, а первый - последним, каждый из которых печатает свою строку.(интервал между ними должен быть достаточно большим, чтобы обеспечить большие «запасы безопасности»)

Я понятия не имею, как, если таковые имеются, это можно сделать без явного / неявного хранения данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...