Чтение/запись файлов с несколькими порядками

У меня есть текстовый файл, который я прочитал, в котором уже есть список имен в алфавитном порядке. Я хочу прочитать каждое имя и расположить его в алфавитном порядке по длине имени в новом файле, который я создаю.

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

Однако мне нужно:

  • все имена длины 1 должны быть перечислены в алфавитном порядке
  • то имена длины 2
  • затем 3 и так далее.

Код, который у меня есть прямо сейчас, получает все правильные имена для длин, которые я хочу, но он размещает все имена в том порядке, в котором они появляются в считываемом файле. Мой вопрос: как мне перечислить все имена длины 1, а затем все длины 2 и так далее в этом порядке?

Я также не могу использовать ничего общего с массивами.

This is what I get in the newly created file from the code i have.

A
Al
B
Bo
C
D
E
Ed
F
G
H
I
J
Jo
K
L
Lu
M
N
O
P
R
S
T
Ty
V
W
Wm

import java.io.*;
import java.util.*;
public class Lab11 {
   public static Scanner input = new Scanner (System.in);
   public static void main (String[] args) throws FileNotFoundException {
      Scanner fileInput = new Scanner(new File("names.txt"));
      PrintStream fileOut = new PrintStream(new File("results.txt"));
      int count1 = 0;
      int count2 = 0;
      int sum = 0;
      while (fileInput.hasNext()) {
         String name = fileInput.next();
         count1++;
         if (name.length() == 1) {
            count2++;
            fileOut.println(name);
         }
         if (name.length() == 2) {
            fileOut.println(name);
         }
         while (fileInput.hasNextInt()) {
            sum += fileInput.nextInt();
         }
      }
      System.out.println(count1);
      System.out.println(count2);
   }
}

person istrikeanywhere    schedule 07.11.2014    source источник
comment
Итак, проблема в том, что они расположены в правильном порядке в соответствии с их длиной, а не в алфавитном порядке?   -  person ChiefTwoPencils    schedule 07.11.2014
comment
Не могли бы вы привести пример того, что находится в файле и ожидаемого результата? Имя вашего класса Lab11 указывает на то, что это домашнее задание, но то, что вы пытались объяснить, кажется мне немного сложным, если только они не рассмотрели инструменты, необходимые для решения в классе (карты, наборы, сортировка и т. д.).   -  person Radiodef    schedule 07.11.2014
comment
Итак, что я хочу сделать, это сначала добавить все имена длины 1 в новый файл, а затем, как только это будет сделано, добавить все имена длины 2 и так далее. Как вы можете видеть, хотя это в алфавитном порядке, но не в порядке их длины.   -  person istrikeanywhere    schedule 07.11.2014


Ответы (2)


Я бы начал с реализации собственного Comparator<String>, который сравнивает длину (ы) перед сравнением значений String (на самом деле неплохо также обрабатывать null), например

static class StringLengthComp implements Comparator<String> {
    @Override
    public int compare(String o1, String o2) {
        if (o1 == null) {
            if (o2 != null) {
                return -1;
            }
            return 0;
        } else if (o2 == null) {
            return 1;
        }
        int r = Integer.valueOf(o1.length()).compareTo(o2.length());
        if (r != 0) {
            return r;
        }
        return o1.compareTo(o2);
    }
}

Затем вы можете сохранить значения в List<String>. и используйте Collections.sort(List, Comparator), а затем распечатать в файл после выполнения. Кроме того, я предлагаю вам использовать try-with-resources, например

public static void main(String[] args) {
    try (Scanner fileInput = new Scanner(new File("names.txt"));
            PrintStream fileOut = new PrintStream(new File("results.txt"));) {
        int sum = 0;
        List<String> names = new ArrayList<>();

        while (fileInput.hasNext()) {
            String name = fileInput.next();
            names.add(name);
            while (fileInput.hasNextInt()) {
                sum += fileInput.nextInt();
            }
        }
        Collections.sort(names, new StringLengthComp());
        for (String name : names) {
            fileOut.println(name);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}
person Elliott Frisch    schedule 07.11.2014
comment
К сожалению, я не могу использовать массивы, потому что мы еще не использовали их в моем классе. - person istrikeanywhere; 07.11.2014

Чтобы распечатать их в алфавитном порядке, вам нужно будет хранить все имена в структуре данных (если вы знаете, сколько имен у вас будет, используйте массив; если вы не знаете, сколько имена, которые у вас будут, используйте список массивов).

После того, как все файлы будут в контейнере, вам придется просмотреть их еще раз, чтобы отсортировать (есть несколько способов сделать это, самым простым является пузырьковая сортировка. Другие, которые могут быть подходящими, включают сортировку выбором и быструю сортировку). ).

Наконец, после того как все они отсортированы, выполните цикл, который проходит по списку x раз, где x — максимальное количество символов в самой длинной строке в списке. Каждый раз, когда вы проходите по списку, распечатывайте символы определенной длины.

person Community    schedule 07.11.2014
comment
К сожалению, я не могу использовать массивы, потому что мы еще не изучили их в классе, а в исходном файле, который я читаю, уже есть все имена в алфавитном порядке. Мне просто нужно отсортировать имена по их длине. - person istrikeanywhere; 07.11.2014
comment
В этом случае вы можете просто перебрать файл x+1 раз. Первый раз, чтобы узнать, какова максимальная длина, которую вы затем используете, чтобы определить, сколько раз нужно пройти файл. for(int i = 0; i ‹ x; i++) if(name.length() == i) fileOut.println(name); - person ; 07.11.2014
comment
Ничего себе, это действительно имеет большой смысл. Могу ли я просто поставить цикл for после моего while hasNext. - person istrikeanywhere; 07.11.2014
comment
Ага. Если я правильно помню, чтобы снова прочитать файл, вам придется закрыть его, а затем снова включить сканер. Итак, fileInput.close(); затем fileInput = новый сканер (новый файл (имена.txt)); - person ; 07.11.2014
comment
Используйте свой цикл while has next, а затем цикл for, а затем в цикле for вам придется сделать еще один while hasNext. Тот факт, что вы не можете хранить эти значения в массиве, является настоящим обломом, лол. - person ; 07.11.2014
comment
@istrikeanywhere Если я не ошибаюсь, Тим Квист предлагает реализовать сортировку выбором: en.wikipedia.org/wiki/Selection_sort - person Kulu Limpa; 07.11.2014