Как сортировать строки (содержащие имена и возраст) сначала по алфавиту, а затем по возрасту в группах имен

Мое задание: взять первоначальный список, поместить его в текстовый файл с именем «Names_ages.txt» и использовать сортировку выбором (никакой другой сортировки) для сортировки по алфавиту. но и сортировать повторяющиеся имена по возрасту. Возраст идет от младшего к старшему.

Исходный список (для сортировки):

Джонс 14

Абрамс 15

Смит 19

Джонс 9

Александр 22

Смит 20

Смит 17

Типпурт 42

Джонс 2

Херкамн 12

Джонс 11

Готовый список (после правильной сортировки):

Абрамс 15

Александр 22

Херкман 12

Джонс 2

Джонс 9

Джонс 11

Джонс 14

Смит 17

Смит 19

Смит 20

Типпурт 42

Мой класс сканера, чтобы сделать текстовый файл массивом (без ошибок, отлично работает)

import java.util.*;
import java.io.*;

public class ScannerClass
{
    public static void main(String[] args)
    {
        ScannerClass.textFile();
    }
    public static void textFile()
    {
        String line;
        String[] names = new String[11];

        try(BufferedReader reader = new BufferedReader(new FileReader("Names_ages.txt")))
        {
            line = reader.readLine();

            for(int i = 0; i < 11; ++i)
            {
                names[i] = line;
                //System.out.println(names[i]);
                line = reader.readLine();
            }
        }
        catch(IOException e)
        {
            System.out.println(e.getMessage());
        }
        SortClass.selectionSort(names);
    }
}

Мой класс сортировки выбора (я публикую то, что он печатает):

import java.util.*;
import java.io.*;

public class SortClass
{
    public static void selectionSort(String names[])
    {
        for(int i=0; i<names.length-1; ++i){
            int minIndex = i;
            for(int j=i+1; j<names.length; ++j)
            {
                if(names[j].compareTo(names[minIndex])<0)
                {
                    int indexChar1 = names[j].indexOf(' ');
                    int indexChar2 = names[minIndex].indexOf(' ');
                    String name1 = names[j].substring(0, indexChar1);
                    String name2 = names[minIndex].substring(0, indexChar2);
                    if(name1.equals(name2))
                    {
                        String number1 = names[j].substring(indexChar1+1); //names[j]
                        String number2 = names[minIndex].substring(indexChar2+1); //names[minIndex]
                        int num1 = Integer.parseInt(number1); //names[j]
                        int num2 = Integer.parseInt(number2); //names[minIndex]
                        if(num1>num2)
                            continue;
                        if(num1<num2)
                            minIndex = j;
                    }
                    else
                        minIndex = j;

                }
            }
            String temp = names[i];
            names[i] = names[minIndex]; 
            names[minIndex] = temp;
        }
        printNames(names);
    }

    public static void printNames(String names[])
    {
        for(int l=0; l<11; l++)
        {
            System.out.println(names[l]);
        }
    }
}

Что выводит моя сортировка:

Абрамс 15

Александр 22

Херкамн 12

Джонс 2

Джонс 11 (эти два нужно поменять местами)

Джонс 9

Джонс 14

Смит 17

Смит 19

Смит 20

Типпурт 42

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


person HardlyTheJavaLegend    schedule 03.03.2017    source источник


Ответы (1)


Вот ваш SortClass после небольшой модификации. Проверьте это и дайте мне знать

import java.util.*;
import java.io.*;

public class SortClass
{
    public static void selectionSort(String names[])
    {
        for(int i=0; i<names.length-1; ++i){
            int minIndex = i;
            for(int j=i+1; j<names.length; ++j)
            {
                int indexChar1 = names[j].indexOf(' ');
                int indexChar2 = names[minIndex].indexOf(' ');
                String name1 = names[j].substring(0, indexChar1);
                String name2 = names[minIndex].substring(0, indexChar2);

                if(name1.compareTo(name2)<0)
                {
                    minIndex = j;
                } else if(name1.compareTo(name2) == 0){

                        String number1 = names[j].substring(indexChar1+1); //names[j]
                        String number2 = names[minIndex].substring(indexChar2+1); //names[minIndex]
                        int num1 = Integer.parseInt(number1); //names[j]
                        int num2 = Integer.parseInt(number2); //names[minIndex]
                        if(num1>num2)
                            continue;
                        if(num1<num2)
                            minIndex = j;

                }
            }
            String temp = names[i];
            names[i] = names[minIndex]; 
            names[minIndex] = temp;
        }
        printNames(names);
    }

    public static void printNames(String names[])
    {
        for(int l=0; l<11; l++)
        {
            System.out.println(names[l]);
        }
    }
}
person Karan Chadha    schedule 03.03.2017
comment
@HardlyTheJavaLegend - в вашей логике была ошибка, особенно в строке if(names[j].compareTo(names[minIndex])<0). Нельзя сравнивать все строки. Логика должна быть - Сравните имена (после разделения), если names[j] (после разделения) лексикографически меньше, чем names[minIndex] (после разделения), то вы обновляете minindex, без сравнения чисел. если имена совпадают ТОЛЬКО ТОГДА вы сравниваете возраст - person Karan Chadha; 03.03.2017