javaalgorithmdata-structuresioshellsort

Shellsorting an array from an input file


The full project is to take data in from a file which is a text file containing a list of all 201 countries and their respective rates of internet use in alphabetical order. Here is an example

Afghanistan                 7
Albania                    63
Algeria                    20
Andorra                    97
Angola                     23
...

With this we have to Shellsort (specifically) the data numerically. I have successfully done this but I only am outputting a list of the percentages, where as I need the countries listed as well. Here is my code:

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

public class InternetUsers {
public static void main(String[] args) throws IOException{
    // TODO Auto-generated method stub

    String populationString = "";
    String[] line = new String[201];
    int populations[] = new int[201];   

    Scanner fileIN = new Scanner(new File("F:/CountrySortedAlpha.txt"));

    while(fileIN.hasNext()){
        for(int i = 0; i < 201; i++){
            populationString = fileIN.nextLine().substring(26, 29);
            populations[i] = Integer.parseInt(populationString.trim());
        }   
        int j;
            for(int gap = populations.length / 2; gap > 0; gap /= 2){
                for (int k = 0; k < populations.length; k++){   
                }
                for (int t = gap; t < populations.length; t++){
                    int tmp = populations[t];
                        for(j = t; j >= gap && (tmp < populations[j - gap]); j -= gap){
                            populations[j] = populations[j - gap];
                        }
                        populations[j] = tmp;
                }
        }
        System.out.println("\nFinal sorted order: ");
        for(int k = 0; k < populations.length; k++){
            System.out.print(populations[k]);
            System.out.println("");
        }
        System.out.println();
    }   
}
}

So my question is how am I to go about outputting the countries as well? do I need to completely redo the way I sorted? Here is my sample output:

 Final sorted order: 
 1
 1
 2
 2
 2
 2
 2
 3
 ....

Solution

  • When you parse the file, you need to store parsed value in a dictionary or some other structure. After you sort, when printing, read the values from dictionary.

    I modified you code to store values in a dictionary, and added comments to the lines I added/modified. I did not touch your sorting algo, so you are still sorting on the same array:

    public static void main(String[] args) throws IOException {
        String populationString = "";
        String[] line = new String[201];
        int populations[] = new int[201];
    
        // Have a dictionary that can store the values you parse
        Map<Integer, String> dictionary = new HashMap<Integer, String>();
    
        Scanner fileIN = new Scanner(new File("F:/CountrySortedAlpha.txt"));
    
        while (fileIN.hasNext()) {
            for (int i = 0; i < 201; i++) {
                // Parse the whole line, this 29 hard coded seems incorrect
                populationString = fileIN.nextLine().substring(0, 29);
                // Grab both values
                String[] splited = populationString.split("\\s+");
                // Country name can have spaces, so take the last elemnt
                populations[i] = Integer.parseInt(splited[splited.length - 1]);
                // Join back values
                String country = populationString.join(" ", splited);
                // Cut off the rate number
                country = country.substring(0, country.lastIndexOf(" "));
                // Store them in your dictionary
                if (dictionary.containsKey(populations[i])) {
                    // If multiple countries have same rate, add them to value, and separate with comma
                    String value = dictionary.get(populations[i]);
                    dictionary.put(populations[i], value + "," + country);
                } else {
                    dictionary.put(populations[i], country);
                }
            }
            int j;
            for (int gap = populations.length / 2; gap > 0; gap /= 2) {
                for (int t = gap; t < populations.length; t++) {
                    int tmp = populations[t];
                    for (j = t; j >= gap && (tmp < populations[j - gap]); j -= gap) {
                        populations[j] = populations[j - gap];
                    }
                    populations[j] = tmp;
                }
            }
            System.out.println("Final sorted order: ");
            for (int k = 0; k < populations.length; k++) {
                // Read the value from dictionary
                String value = dictionary.get(populations[k]);
                // For duplicates skip, that entry gets deleted after values were printed
                if (value == null) {
                    continue;
                }
    
                // If multiple countries had the same rate, they were stored as comma separated value
                String[] countries = value.split(",");
                for (String country : countries) {
                    // You can print rate, or country, or both
                    System.out.println(populations[k] + " " + country);
                }
    
                // Remove from dictionary, because we already printed all countries with the same rate
                dictionary.remove(populations[k]);
            }
            System.out.println();
        }
    
        // Don't forget to close the file
        fileIN.close();
    }