Разделение пермутированного списка слов

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

    ATHROCYTESDISHLIKEIRRECOVERABLENESSESEMBRITTLEMENTSYOUNGSOVER

но когда я копирую и вставляю его, он выглядит следующим образом:

    ATHROCYTES
    DISHLIKE
    IRRECOVERABLENESSES
    EMBRITTLEMENTS
    YOUNGS
    OVER

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

    while (dis.available() != 0) {
            System.out.println(dis.readLine());
        }

распечатывает документ в правильном формате, как если бы я скопировал и вставил его. Я использую этот код, чтобы попытаться загрузить его в массив:

    String[] store = sb.toString().split(",");

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

    String[] store = sb.toString().split(scan.nextLine());

Оба они дают мне один и тот же результат, слова печатаются в одной строке. Кто-нибудь знает, как я могу правильно отформатировать результаты в массив?

Я включил остальную часть своего кода, так как возможно, что проблема возникает в другом месте:

public class InsertionSort {

public static String[] InsertSort(String[] args) {
    int i, j;
    String key;

    for (j = 1; j < args.length; j++) { //the condition has changed
        key = args[j];
        i = j - 1;
        while (i >= 0) {
            if (key.compareTo(args[i]) > 0) {//here too
                break;
            }
            args[i + 1] = args[i];
            i--;
        }
        args[i + 1] = key;
        return args;
    }

    return args;
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) throws FileNotFoundException, IOException {
    Scanner scan = new Scanner(System.in);
    System.out.println("Insertion Sort Test\n");


    int n;
    String name, line;


    System.out.println("Enter name of file to sort: ");
    name = scan.next();

    BufferedReader reader = new BufferedReader(new FileReader(new File(name)));
    //The StringBuffer will be used to create a string if your file has multiple lines
    StringBuffer sb = new StringBuffer();

    File file = new File(name);
    FileInputStream fis = null;
    BufferedInputStream bis = null;
    DataInputStream dis = null;

    try {
        fis = new FileInputStream(file);

        // Here BufferedInputStream is added for fast reading.
        bis = new BufferedInputStream(fis);
        dis = new DataInputStream(bis);

        // dis.available() returns 0 if the file does not have more lines.
        while (dis.available() != 0) {

  // this statement reads the line from the file and print it to
            // the console.
            System.out.println(dis.readLine());
        }

        // dispose all the resources after using them.
        fis.close();
        bis.close();
        dis.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    while((line = reader.readLine())!= null){

    sb.append(line);

}

    //We now split the line on the "," to get a string array of the values
    String[] store = sb.toString().split("/n");
     System.out.println(Arrays.toString(store));
    /* Call method sort */
    InsertSort(store);

    n = store.length;
    FileWriter fw = new FileWriter("sorted.txt");


for (int i = 0; i < store.length; i++) {
  fw.write(store[i] + "\n");
}
fw.close();
     }

}

person user3068177    schedule 13.09.2015    source источник
comment
Вы пробовали блокнот++? Он работает намного лучше, чем блокнот. Строки, вероятно, разделены разрывом строки (\n). Это должен быть ваш разделитель. Я не знаком с Java, но это, похоже, ваша проблема.   -  person Steven Walton    schedule 13.09.2015
comment
Я просто использовал блокнот, так как это файл .txt. Я делаю все свое кодирование в NetBeans. С учетом сказанного я попытался отредактировать свой код, чтобы сделать разделение \n, что дало мне: String[] store = sb.toString().split(/n); но я все равно получаю тот же результат, что и все они находятся на одной линии.   -  person user3068177    schedule 13.09.2015
comment
Ну, вы использовали неправильный слеш. Кроме того, notepad++ лучше читает файлы, именно поэтому я его и предлагаю.   -  person Steven Walton    schedule 13.09.2015


Ответы (2)


У вас есть преждевременное заявление о возврате здесь:

  args[i + 1] = key;
  return args; // the cause
}

Удалите его, и он должен быть исправлен:

[ATHROCYTES, DISHLIKE, IRRECOVERABLENESSES, EMBRITTLEMENTS, YOUNGS, OVER]

 DISHLIKE -> ATHROCYTES = 3
 IRRECOVERABLENESSES -> DISHLIKE = 5
 EMBRITTLEMENTS -> IRRECOVERABLENESSES = -4
 EMBRITTLEMENTS -> DISHLIKE = 1
 YOUNGS -> IRRECOVERABLENESSES = 16
 OVER -> YOUNGS = -10
 OVER -> IRRECOVERABLENESSES = 6

[ATHROCYTES, DISHLIKE, EMBRITTLEMENTS, IRRECOVERABLENESSES, OVER, YOUNGS]

Полный код:

public static String[] InsertSort(String[] args) {
  int i, j;
  String key;

  System.out.println(Arrays.toString(args));

  for (j = 1; j < args.length; j++) { //the condition has changed
    key = args[j];
    i = j - 1;
    while (i >= 0) {
      System.out.printf(" %s -> %s = %d\n", key, args[i], key.compareTo(args[i]));
      if (key.compareTo(args[i]) > 0)//here too
        break;
      args[i + 1] = args[i];
      i--;
    }
    args[i + 1] = key;
  }

  return args;
}

public static void main(String[] args) throws FileNotFoundException, IOException {
  Scanner scan = new Scanner(System.in);
  System.out.println("Insertion Sort Test\n");

  System.out.println("Enter name of file to sort: ");
  String name = scan.nextLine();

  File file = new File(name);
  String sb = (new Scanner(file)).useDelimiter("\\Z").next();

  //We now split the line on the "," to get a string array of the values
  List<String> list = Arrays.asList(sb.split("\n\r?"));

  ArrayList<String> list2 = new ArrayList<>();
  list.stream().forEach((s) -> {
    list2.add(s.trim());
  });

  System.out.println(list2);
  /* Call method sort */
  String[] store = list2.toArray(new String[]{});

  InsertSort(store);

  System.out.println(Arrays.asList(store));

  int n = store.length;

  try (FileWriter fw = new FileWriter("sorted.txt")) {
    StringBuilder b = new StringBuilder();
    for (String s: store)
      b.append(s).append("\n");

    fw.write(b.toString());
  }
}
person ankhzet    schedule 13.09.2015
comment
Это, похоже, не изменило результат. - person user3068177; 13.09.2015
comment
Так что мне просто нужно удалить возвращаемые аргументы;? Если это так, я пробовал это раньше и получил тот же результат. - person user3068177; 13.09.2015
comment
В строке кода list.stream().forEach((s) -> { я получаю сообщение об ошибке, сообщающее, что здесь не ожидается лямбда-выражение. Есть ли другой способ обойти эту ошибку? Похоже, мне нужно использовать обновленную версию Явы. - person user3068177; 13.09.2015
comment
Кажется, он работает правильно. Я действительно ценю твою помощь. - person user3068177; 13.09.2015
comment
Добро пожаловать =) Лямбда-выражение можно переписать как простое for (String s: list) list2.add(s.trim()); - person ankhzet; 13.09.2015

Причина, по которой ваш файл отображается в виде одной строки в Блокноте Windows, вероятно, заключается в том, что Блокнот распознает только CRLF, \n\r как новую строку, в то время как большинство программ UNIX рассматривают только LF, \n как новую строку. Ваш текстовый файл, вероятно, был сгенерирован программой UNIX. Дополнительные пояснения можно найти здесь.

Теперь о вашем коде.

String[] store = sb.toString().split(scan.nextLine());

Эта строка кода передает split() любую первую строку вашего сканера. Я понятия не имею, что это может быть, но разделение будет искать экземпляры этого элемента и разбивать строку на эти экземпляры.

То, что вы хотите, это

String[] store = sb.toString.split("\n\r?");

String.split() принимает регулярное выражение Java. Регулярное выражение

"\n\r?"

Эквивалентно фразе «Разделить при переводе строки или CRLF».

Кроме того, я бы рекомендовал анализировать вашу строку с помощью Scanner вместо того, чтобы пытаться разбить ее на массив.

Scanner scan = new Scanner(sb.toString());
while(scan.hasNextLine()) {
    //Do stuff with scan.nextLine()
}

Изменить: помните, что экранированные символы используют обратную косую черту, а не прямую косую черту. Например, \n или \r.

person Dylan Culfogienis    schedule 13.09.2015
comment
"\n\r|[\n\r]" можно упростить до "\n\r?", афаик - person ankhzet; 13.09.2015
comment
"\n\r|[\n\r]" работает как с окончаниями строк UNIX, так и с Windows. "\n\r" в этом случае будет работать, но лучше использовать подход, который будет работать всегда. Сканеры Java используют "\r\n|[\n\r\u2028\u2029\u0085]" в качестве регулярного выражения по умолчанию. - person Dylan Culfogienis; 13.09.2015
comment
а, регулярное выражение "\n\r?" равно "\n\r|[\n\r]", оба они будут захватывать одни и те же последовательности (\n, \n\r). или вы когда-нибудь смотрели модификатор ? на \r char? - person ankhzet; 13.09.2015
comment
Мои извинения, я действительно сделал. Изменил мой ответ, чтобы соответствовать. "\n\r?" делает что-то другое, но в данном случае это не имеет значения. - person Dylan Culfogienis; 13.09.2015
comment
Попробовав все различные опубликованные решения, похоже, у меня есть другие проблемы, поскольку я все еще нахожусь в конце выполнения, получая тот же несортированный список слов. - person user3068177; 13.09.2015