搜索大数组以获取最小数字

时间:2013-12-01 07:51:54

标签: java arrays loops

嘿大家所以我有一个非常大的数组,其中列出了名称和受欢迎程度等级,通常数字越低,该名称越受欢迎。我需要一种方法来搜索数组,找出特定十年中20个最低数字。那么让我告诉你我的列表和代码是什么。

This is my list.

这是我的代码:

名称

public class Name{

private String givenName;
private int[] ranks = new int[11];

public Name(String name, int[] popularityRanks){
    givenName = name;

    for (int i = 0; i < 11; i++){
        ranks[i] = popularityRanks[i];
    }
}

public String getName(){
    return givenName;
}

public int getPop(int decade){
    if (decade >= 1 && decade <= 11){
        return ranks[decade];
    }
    else{
        return -1;
    }
}

public String getHistoLine(int decade){
    String histoLine = ranks[decade] + ": ";

    return histoLine;
}

public String getHistogram(){
    String histogram = "";

    for (int i = 0; i < 11; i++){
        histogram += ranks[i] + ": " + this.getHistoLine(i)
                + "\n";
    }

    return histogram;
}
}

然后是NameApp:

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

public class NameApp{

private static boolean validInput;
private static boolean stillWorking = true;
private static boolean validDecade;

static Scanner keyboard = new Scanner(System.in);

public static void main(String[] args) throws FileNotFoundException{
    String[] nameArray = readNamesFile();
    Name[] list = new Name[nameArray.length];

    loadNames(list, nameArray);

    char choice;

    do {

        do {

            displayMenu();
            choice = getUserInput();

        } while (!validInput);

        switch (choice){
            case 'A':
                    displayHistogram(list);
                break;
            case 'B':
                    compareTwoNames(list);
                break;
            case 'C':
                    displayTopTenNames(list);
                break;
            case 'D':
                    writeAnomaliesToFile(list);
                    stillWorking = false;
                break;
            default:
                break;
        }

    } while (stillWorking);
}   

private static String[] readNamesFile() throws FileNotFoundException{
    String[] nameArray = new String[4429];

    Scanner inputStream = null;
    String fileName = "names.txt";
    inputStream = new Scanner (new File(fileName));

    int i = 0;

    while (inputStream.hasNextLine()){
        nameArray[i] = inputStream.nextLine();

        i++;
    }

    inputStream.close();
    return nameArray;
}

private static void loadNames(Name[] list, String[] nameArray){
    int length;
    int spacePos;
    int[] popRanks = new int[11];
    String name;
    String linePop;

    for (int i = 0; i < nameArray.length; i++){
        length = nameArray[i].length();

        spacePos = nameArray[i].indexOf(" ");

        name = nameArray[i].substring(0,spacePos);
        linePop = nameArray[i].substring(spacePos + 1, length);

        for (int j = 0; j < 11; j++){
            popRanks[j] = Integer.parseInt(linePop.split(" ")[j]);
        }

        list[i] = new Name(name, popRanks);
    }
}

private static void displayMenu(){
    System.out.println("Enter the character corresponding to your selection:");
    System.out.println("\ta - Print histogram for a name");
    System.out.println("\tb - Compare two names in a decade");
    System.out.println("\tc - Print top ten names for a decade");
    System.out.println("\td - Quit (display file anomalies)");
}

private static char getUserInput(){

    String selection = keyboard.nextLine();
    System.out.println("   Your selection: " + selection);

    checkUserInput(selection);

    char choice = stringToChar(selection);

    return choice;
}

private static boolean checkUserInput(String selection){

    if (!selection.equalsIgnoreCase("a") && !selection.equalsIgnoreCase("b") && !selection.equalsIgnoreCase("c") && !selection.equalsIgnoreCase("d")){
        System.out.println("Invalid input. Try again...");
        return validInput = false;
    }
    else {          
        return validInput = true;
    }

}

private static char stringToChar(String selection){
    char choice = selection.charAt(0);

    choice = Character.toUpperCase(choice);

    return choice;
}

private static void displayHistogram(Name[] list){
    String nameInput;
    String histogram;
    int nameLocation;

    nameInput = nameEntry();

    nameLocation = checkListArray(nameInput, list);

    histogram = list[nameLocation].getHistogram();

    System.out.println("Histogram for name, " + list[nameLocation].getName() + ":");
    System.out.println(histogram);
}

private static void compareTwoNames(Name[] list){
    String nameOne;
    String nameTwo;
    String oneHistoLine;
    String twoHistoLine;
    int oneLocation;
    int twoLocation;
    int decade;

    nameOne = nameEntry();
    oneLocation = checkListArray(nameOne, list);

    nameTwo = nameEntry();
    twoLocation = checkListArray(nameTwo, list);

    decadeMenu();
    decade = decadeSelection();

    oneHistoLine = list[oneLocation].getHistoLine(decade);
    twoHistoLine = list[twoLocation].getHistoLine(decade);

    System.out.println("Data for " + list[oneLocation].getName());
    System.out.println(" " + oneHistoLine);
    System.out.println("Data for " + list[twoLocation].getName());
    System.out.println(" " + twoHistoLine);
}

private static void displayTopTenNames(Name[] list){
    int decade;
    int temp = 1000;
    int tempTwo;
    String[] topTen = new String[20];

    decadeMenu();
    decade = decadeSelection();

    for (int i = 0; i < 20; i++){
        for (int j = 0; j < list.length; j++){
            if (list[j].getPop(decade) > 0 && list[j].getPop(decade) < temp){
                temp = list[j].getPop(decade);
                tempTwo = 
            }
        }
    }

}

private static void writeAnomaliesToFile(Name[] list){

}

private static String nameEntry(){
    String nameInput = "";

    System.out.println("Enter a name: ");

    nameInput = keyboard.nextLine();

    return nameInput;

}

private static int checkListArray(String nameInput, Name[] list){
    int nameLocation = -1;
    int listLength = list.length;

    for (int i = 0; i < listLength; i++){
        if (nameInput.equalsIgnoreCase(list[i].getName())){
            return nameLocation = i;
        }
    }

    if (nameLocation == -1){
        System.out.println("The name, " + nameInput + ", was not found!");
        return nameLocation;
    }
    return nameLocation;
}

private static void decadeMenu(){
    System.out.println("Enter number correpsonding to your decade:");
    System.out.println("   1 - 1900-1909");
    System.out.println("   2 - 1910-1919");
    System.out.println("   3 - 1920-1929");
    System.out.println("   4 - 1930-1939");
    System.out.println("   5 - 1940-1949");
    System.out.println("   6 - 1950-1959");
    System.out.println("   7 - 1960-1969");
    System.out.println("   8 - 1970-1979");
    System.out.println("   9 - 1980-1989");
    System.out.println("   10 - 1990-1999");
    System.out.println("   11 - 2000-2005");
}

private static int decadeSelection(){
    String decadeChoice;
    int decade;

    do {
        System.out.println("Enter a decade: ");
        decadeChoice = keyboard.nextLine();

        decade = checkDecade(decadeChoice);

    } while (!validDecade);

    return decade;
}

private static int checkDecade(String decadeChoice){
    int decade = 0;

    try {
        decade = Integer.parseInt(decadeChoice);
    }
    catch (Exception e){
        System.out.println("That is not an integer. Please try again.");

        return decade;
    }

    if (decade < 1 || decade > 11){
        System.out.println("Enter an integer between 1 and 11");

        validDecade = false;
        return decade;
    }
    else {
        validDecade = true;

        return decade;
    }
}
}

所以我需要帮助的是displayTopTenNames方法。我有点搞砸了它,但是我提出的每个循环总是会产生我不想要的重复...无论如何我的输出应该是这样的:

1910 - 1919年间十个最受欢迎的名字(男性和女性)是:

约翰(1)玛丽(1)
    海伦(2)威廉(2)
    多萝西(3)詹姆斯(3)
    玛格丽特(4)罗伯特(4)
    约瑟夫(5)露丝(5)
    乔治(6)米尔德里德(6)
    安娜(7)查尔斯(7)
    爱德华(8)伊丽莎白(8)
    弗朗西斯(9)弗兰克(9)
    玛丽(10)沃尔特(10)

所以,非常感谢您的帮助,并提前致谢。

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

可能有更有效的方法来做到这一点,但这显示了理论。您维护一个包含20个项目的小清单。您扫描大型列表以查看它是否是您的短名单的候选者。如果列表小于20,则会添加任何内容。如果已达到20,则检查列表中的任何内容是否大于您要添加的项目。如果是,则该项目被驱逐并用较小的值替换。

public class Low20 {
    private List<Integer> list = new ArrayList<Integer>();

    public static final void main(String[] args) {
        new Low20();
    }

    public Low20() {
        Random random = new Random();
        for (int x=0;x<100000;x++) {
            add(random.nextInt(100000));
        }
        System.out.println(list);
    }

    public void add(int value) {
        if (list.size() < 20) {
            list.add(value);
        } else {
            for (int x=0;x<list.size();x++) {
                if (list.get(x) > value) {
                    list.remove(x);
                    list.add(value);
                    return;
                }
            }
        }
    }
}

结果。 (随机数,但最低20)。然后,您可以对这些进行排序,或将排序合并到逐出算法中。

[6,0,5,17,18,11,10,27,22,27,28,16,34,33,0,8,28,0,15,14]

此方法优于在列表中使用毯式排序,这是因为您的列表不必适合内存,可以从文件或数据库扫描中应用。