4

The goal is to have a sorted input.txt such as:

1 one
2 two
4 four
10 ten

From an input.txt of:

2 two
4 four
1 one
10 ten

So far in my code I have sorted the number array and now I have to change the String array since it's paired with the num array. How do I do that?

import java.util.*;
import java.io.*;
//Noah Cavazos

public class SortingNumbers{
   public static void main(String[] args) throws FileNotFoundException {
      Scanner fin = new Scanner(new File("input.txt"));
      int[] nums = new int[100];
      String[] texts = new String[100];
      int cnt = 0;
      while(fin.hasNextInt()){
         nums[cnt] = fin.nextInt();
         texts[cnt] = fin.nextLine();
         cnt++;
      }
      int[] Numbers = new int[cnt];
      String[] Words = new String[cnt];
      for(int i = 0; i < Numbers.length; i++){
         Numbers[i] = nums[i];
         Words[i] = texts[i];
         //System.out.println(Numbers[i] + Words[i]);
      }
      Arrays.sort(Numbers);
      //Arrays.sort(Words); < Alphabetically

   }

}
Jens
  • 67,715
  • 15
  • 98
  • 113
  • 3
    A different approach is to create a class which holds **both** the numeric value and the String value., then sort based on the numeric value from the class. Also, since it's unknown how many items are in the input, consider using a List instead of an array. – Andrew S Dec 01 '18 at 22:18

5 Answers5

3

Because you are keeping the strings and the numbers in separate arrays, once you sort one of the arrays you lose the relationships between the string-number pairs.

As mentioned by @Andrew S, the way to do this is to create a new class (Pair) in which you hold both the number and the string. You will read from the file into an array of objects of type Pair, instead of reading the numbers and strings separately. When the array is sorted, the numbers and their corresponding texts will be sorted together.

To be able to sort an array containing elements of type Pair, we need to specify how exactly to compare two pairs. This is where the Comparator comes in. It will tell the sorting function the criteria by which the objects in the array will be compared. In this case, two Pair objects are compared by their number fields.

public class Pair {

  private int number;
  private String text;
  // getters and setters, constructor, toString() etc.
}


public static void main(String[] args) throws FileNotFoundException{
    Scanner fin = new Scanner(new File("input.txt"));
    int[] nums = new int[100];
    String[] texts = new String[100];
    int cnt = 0;
    while(fin.hasNextInt()){
        nums[cnt] = fin.nextInt();
        texts[cnt] = fin.nextLine();
        cnt++;
    }
    Pair[] pairs = new Pair[cnt];
    for(int i = 0; i < cnt; i++){
        pairs[i] = new Pair(nums[i], texts[i]);
    }
    Arrays.sort(pairs, new Comparator<Pair>() {
        @Override
        public int compare(Pair o1, Pair o2) {
            return Integer.compare(o1.getNumber(), o2.getNumber());
        }
    });
    for (Pair p: pairs) {
        System.out.println(p);
    }

}
Anda S
  • 41
  • 4
  • 1
    Good Answer. Tip: No need to write the `Pair` class. Java already provides a type-safe interface [`Map.Entry`](https://docs.oracle.com/javase/9/docs/api/java/util/Map.Entry.html) with a couple of implementations, [one mutable](https://docs.oracle.com/javase/9/docs/api/java/util/AbstractMap.SimpleEntry.html) and [one not](https://docs.oracle.com/javase/9/docs/api/java/util/AbstractMap.SimpleImmutableEntry.html). See [this Question](https://stackoverflow.com/q/7316571/642706). – Basil Bourque Dec 01 '18 at 22:51
  • 1
    better to use `Integer.compare(o1.getNumber(), o2.getNumber())` instead of `o1.getNumber() - o2.getNumber()` – Ousmane D. Dec 01 '18 at 22:55
2

I'd like to recommend an easier approach to read your text file and sorting the items.

List<SimpleEntry<Integer, String>> result;
try (Stream<String> stream = Files.lines(Paths.get("input.txt"))) {
   result = stream.map(s -> s.split("\\s"))
                  .map(a -> new SimpleEntry<>(Integer.parseInt(a[0]), a[1]))
                  .sorted(Comparator.comparingInt(SimpleEntry::getKey))
                  .collect(Collectors.toCollection(ArrayList::new));
} catch (IOException e) { e.printStackTrace(); }

This solution uses SimpleEntry to contain both the integer value and the String value so that after sorting we can maintain related data.

On another note, you may want to create your own custom class with these two fields as mentioned by @Andrew S instead of SimpleEntry.

Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
0

You cannot sort one arrays without another, because you lost relations (which row in unsoted arrays belongs to one in sorted).

To fix this, you could maintain the relation in a map, but smarter is to create class and sort instances of such class (Comparable/Comparator).

Betlista
  • 10,327
  • 13
  • 69
  • 110
0

To do this you have to link the integers to the strings, you can do this with a HashMap were save while you are reading the file in the integers as key a the word as value. After sorting your numbers array you can simply cycle through the array of numbers and make a new array of strings where you put the value to the integer in it which you saved before in the HashMap.

Another method would be to write your own sorting algorithm and change the string array as you change the integer array in the same way.

0

When you track a pair of values, one value leading to the other value, that is commonly known as a key-value or attribute-value pair.

Map

In Java, we track one value by another using the Map interface. When you put in a key-value pair, you can later retrieve the value by specifying the key. Like a dictionary, where a word leads to a definition.

SortedMap

If you want the keys kept in sorted order, use the SortedMap sub-interface.

TreeMap

One implementation of a SortedMap that comes bundled with Java is the TreeMap class.

Using Java Generics, you specify the data type to used as keys and the data type to be used as values. In our case here, that would be Integer and String.

SortedMap< Integer , String > map = new TreeMap<>() ;

As you gather your inputs, parse the input meant to be a number as a Integer. Then store with its partnering String object into the TreeMap.

Integer integer = Integer.getInteger( "1" ) ;
String string = "one" ;

map.put( integer , string ) ;

When you loop these entries, they will be presented to you in the sorted order of the keys, sorted numerically because they are of type Integer.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154