java - 在对象数组中搜索某些值

标签 java arrays loops object

大家好,我被困在这个程序的最后部分,我一直在做作业。因此,通常我会得到一大堆名字和数字,这些名字和数字代表了某些几十年里名字的受欢迎程度。 This is what the file looks like <-----这是查看名称.txt 的链接

所以我创建了一个对某个十年内的列表进行排序的方法,即 getIndexOfSmallest 和交换。每个十年都有两个排名相同的名字,因此在 1900-1909 年间,有两个名字排名第一,两个名字排名第二,两个名字排名第三,依此类推。程序的最后一部分,也是我需要帮助的部分,假设对对象数组进行排序,并找到一个等级只有一个名称或某个等级没有名称的任何十年。输出将发送到文件和 it will look like this. <------这是查看预期输出的另一个链接

这就是我的代码的样子。这是我创建对象的名称代码:

public class Name{

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

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 >= 0 && decade <= 10){
        return ranks[decade];
    }
    else{
        return -1;
    }
}

public String getHistoLine(int decade){     
    String histoLine = ranks[decade] + ": ";
    double popularity = (1000 - ranks[decade]) / 11.7;
    int histo = (int)popularity;

    if(popularity != 0){

        for (int i = 0; i < histo; i++){
            histoLine += "*";
        }
    }

    return histoLine;
}

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

    for (int i = 0; i < 11; i++){
        histogram += 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;
private static boolean validName;

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

// Main method
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);
}   

/*
 * This method will read the file name names.txt and load the names and populations into a string array.
 */
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;
}

/*
 * load names method will take a Name array and the string array from the readNamesFile method. This method will split the names and the population ranks and send them to the constructor in Name.java.
 */
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);
    }
}

/*
 * displayMenu method will display the menu that the user will select their program function.
 */
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)");
}

/*
 * getUserInput is a method that will accept a string input from the user it will send this string to two different helper methods.
 */
private static char getUserInput(){

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

    checkUserInput(selection);

    char choice = stringToChar(selection);

    return choice;
}

/*
 * helper method: checkUserInput will accept the user input from getUserInput and test the input to see if the input is a valid input from the user. If it is not set the instance boolean variable to false if it is set it to true.
 */
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;
    }

}

/*
 * helper method: stringToChar method will take the input that the user entered after it has been tested to see if it is valid and this method will change the input to a character value. This will also make the character to an upper case letter.
 */
private static char stringToChar(String selection){
    char choice = selection.charAt(0);

    choice = Character.toUpperCase(choice);

    return choice;
}

/*
 * Menu option: A. This method will take a user input for the name they want and display the histogram for the selected name.
 */
private static void displayHistogram(Name[] list){
    String nameInput;
    String histogram;
    int nameLocation;

    do {
        nameInput = nameEntry();

        nameLocation = checkListArray(nameInput, list);

        if (!validName){
            System.out.println("The name, " + nameInput + ", was not found!");
        }

    } while (!validName);

    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;

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

        if (!validName){
            System.out.println("The first name, " + nameOne + ", was not found!");
        }

    } while (!validName);

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

        if (!validName){
            System.out.println("The second name, " + nameTwo + ", was not found!");
        }

    } while(!validName);


    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 count = 0;
    int l = 0;
    String[] decadeName = new String[20];
    Name[] temp = new Name[list.length];

    decadeMenu();
    decade = decadeSelection();

    for (int i = 0; i < list.length; i++){
        temp[i] = list[i];
    }

    for (int index = 0; index < temp.length; index++){
        int smallestIndex = getIndexOfSmallest(decade, index, temp);
        interchange(decade, index, smallestIndex, temp);
    }

    do {

        if (temp[l].getPop(decade) == 0){
            l++;
        } 
        else {
            decadeName[count] = temp[l].getName() + " " + "(" + temp[l].getPop(decade) + ")";

            count++;
            l++;
        }

    } while (count < 20);   

    writeTopTen(decadeName, decade);
}

private static void writeAnomaliesToFile(Name[] list){
    System.out.println("Terminating... but first the anomalies in the data file:");

    checkAnomalies(list);

    System.out.println("Anomalies written to anomalies.txt.");
}

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())){
            validName = true;
            return nameLocation = i;
        }
    }

    if (nameLocation == -1){
        validName = false;
        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.");

        validDecade = false;
        return decade;
    }

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

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

        decade = changeDecade(decade);

        return decade;
    }
}

private static int changeDecade(int decade){
    int newDecade = 0;

    switch (decade){
        case 1:
            newDecade = 0;
            break;
        case 2:
            newDecade = 1;
            break;
        case 3:
            newDecade = 2;
            break;
        case 4:
            newDecade = 3;
            break;
        case 5:
            newDecade = 4;
            break;
        case 6:
            newDecade = 5;
            break;
        case 7:
            newDecade = 6;
            break;
        case 8:
            newDecade = 7;
            break;
        case 9:
            newDecade = 8;
            break;
        case 10:
            newDecade = 9;
            break;
        case 11:
            newDecade = 10;
            break;
        default:
            break;
    }

    return newDecade;
}

private static int getIndexOfSmallest(int decade, int startIndex, Name[] temp){
    int min = temp[startIndex].getPop(decade);
    int indexOfMin = startIndex;

    for (int index = startIndex + 1; index < temp.length; index++){
        if (temp[index].getPop(decade) < min){
            min = temp[index].getPop(decade);
            indexOfMin = index;
        }
    }

    return indexOfMin;
}

private static void interchange(int decade, int i, int j, Name[] temp){
    Name tempInt = temp[i];
    temp[i] = temp[j];
    temp[j] = tempInt;
}

private static String decadeYears(int decade){      
    String decadeYear = "";

    switch (decade){
        case 0:
            decadeYear = "1900 - 1909";
            break;
        case 1:
            decadeYear = "1910 - 1919";
            break;
        case 2:
            decadeYear = "1920 - 1929";
            break;
        case 3:
            decadeYear = "1930 - 1939";
            break;
        case 4:
            decadeYear = "1940 - 1949";
            break;
        case 5:
            decadeYear = "1950 - 1959";
            break;
        case 6:
            decadeYear = "1960 - 1969";
            break;
        case 7:
            decadeYear = "1970 - 1979";
            break;
        case 8:
            decadeYear = "1980 - 1989";
            break;
        case 9:
            decadeYear = "1990 - 1999";
            break;
        case 10:
            decadeYear = "2000 - 2005";
            break;
        default:
            break;
    }

    return decadeYear;
}

private static void writeTopTen(String[] decadeName, int decade){
    String years;

    years = decadeYears(decade);

    System.out.println("Ten most popular names (male and female) during the decade " + years + " were:");

    for (int i = 0; i < 20; i += 2){
        System.out.printf("%20s\t%20s\n", decadeName[i],decadeName[i + 1]);
    }
}

private static void checkAnomalies(Name[] list){
    Name[] temp = new Name[list.length];
    int anomalyCount = 0;
    int popTwo = 0;
    int popOne = 0;
    String[] anomalies = new String[list.length];

    for (int i = 0; i < list.length; i++){
        temp[i] = list[i];
    }

    for (int decade = 0; decade < 11; decade++){

        for (int index = 0; index < temp.length; index++){
            int smallestIndex = getIndexOfSmallest(decade, index, temp);
            interchange(decade, index, smallestIndex, temp);
        }

        int rank = 0;

        for (int i = 1; i < temp.length - 1; i += 2){

            popOne = temp[i].getPop(decade);
            popTwo = temp[i+1].getPop(decade);

            if (popOne != 0){
                rank++;
            }

            if (popOne  == rank && popTwo != rank){
                String decadeYear = decadeYears(decade);
                anomalies[anomalyCount] = "One name (" + temp[i].getName() + ") for " + decadeYear + ", rank " + temp[i].getPop(decade) + ".";
                anomalyCount++;
            }
            else if (popOne != rank && popTwo == rank){
                String decadeYear = decadeYears(decade);
                anomalies[anomalyCount] = "One name (" + temp[i+1].getName() + ") for " + decadeYear + ", rank " + temp[i+1].getPop(decade) + ".";
                anomalyCount++;
            }
            else if (popOne != rank && popTwo != rank){
                String decadeYear = decadeYears(decade);
                anomalies[anomalyCount] = "No names for " + decadeYear + ", rank " + temp[i].getPop(decade) + ".";
                anomalyCount++;
            }

        }
    }
}
}

这是我的教授提供的信息:

有 1,065 个异常:在某些情况下,十年内只有一个名字具有特定排名,或者在其他情况下,十年内没有名字具有特定排名。由于需要检查 11 个十进制和 999 个等级,1065 仅占损坏或异常名称对的 9.7% 左右。每个十年 (11) 中的每个等级 (999) 应该有一对名字:这给出了 10,989 个名字对。为此,您的代码需要检查每个十年中每个排名的每个名称,以便找到所有 1065 个异常。

当我调试程序时,我发现排名以奇数结尾。这就是为什么我在 checkAnomalies 中从 1 而不是 0 开始循环(考虑到在 0 时,名称排名将为 0,并且被认为是选择的名称为 1000 或更少)。当我运行程序时:

String[] anomalies = new String[1065];

我收到此错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1065
at NameApp.checkAnomalies(NameApp.java:512)
at NameApp.writeAnomaliesToFile(NameApp.java:259)
at NameApp.main(NameApp.java:43)

当我将代码更改为:

String[] anomalies = new String[temp.length];

我收到此错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4429
at NameApp.checkAnomalies(NameApp.java:502)
at NameApp.writeAnomaliesToFile(NameApp.java:259)
at NameApp.main(NameApp.java:43) 

我认为我的错误在我的循环中,但我不知道在哪里..我认为我的循环发现的错误比实际错误要多..只是想知道是否有人可以帮助我解决这个问题..它是确实是我唯一需要的部分了。提前致谢

编辑:

这是我需要帮助的相关代码:

private static void writeAnomaliesToFile(Name[] list){
System.out.println("Terminating... but first the anomalies in the data file:");

checkAnomalies(list);

System.out.println("Anomalies written to anomalies.txt.");
}

调用的方法:

private static void checkAnomalies(Name[] list){
Name[] temp = new Name[list.length];
int anomalyCount = 0;
int popTwo = 0;
int popOne = 0;
String[] anomalies = new String[list.length];

for (int i = 0; i < list.length; i++){
    temp[i] = list[i];
}

for (int decade = 0; decade < 11; decade++){

    for (int index = 0; index < temp.length; index++){
        int smallestIndex = getIndexOfSmallest(decade, index, temp);
        interchange(decade, index, smallestIndex, temp);
    }

    int rank = 0;

    for (int i = 1; i < temp.length - 1; i += 2){

        popOne = temp[i].getPop(decade);
        popTwo = temp[i+1].getPop(decade);

        if (popOne != 0){
            rank++;
        }

        if (popOne  == rank && popTwo != rank){
            String decadeYear = decadeYears(decade);
            anomalies[anomalyCount] = "One name (" + temp[i].getName() + ") for " + decadeYear + ", rank " + temp[i].getPop(decade) + ".";
            anomalyCount++;
        }
        else if (popOne != rank && popTwo == rank){
            String decadeYear = decadeYears(decade);
            anomalies[anomalyCount] = "One name (" + temp[i+1].getName() + ") for " + decadeYear + ", rank " + temp[i+1].getPop(decade) + ".";
            anomalyCount++;
        }
        else if (popOne != rank && popTwo != rank){
            String decadeYear = decadeYears(decade);
            anomalies[anomalyCount] = "No names for " + decadeYear + ", rank " + temp[i].getPop(decade) + ".";
            anomalyCount++;
        }

    }
}
}

最佳答案

解决了我自己必须 sleep 的问题:

    private static void checkAnomalies(Name[] list) 
        throws FileNotFoundException{
    Name[] temp = new Name[list.length];
    String[] anomalies = new String[1065];
    int anomalyCount = 0;

    for (int i = 0; i < list.length; i++){
        temp[i] = list[i];
    }

    for (int decade = 0; decade < 11; decade++){
        for (int ranks = 1; ranks < 1000; ranks++){
            int found = 0;
            String tempName = "";

            String decadeYear = decadeYears(decade);

            for (int i = 0; i < temp.length; i++){
                if (temp[i].getPop(decade) == ranks){
                    found++;
                }

                if (found == 1 && 
                        temp[i].getPop(decade) == ranks){
                    tempName = temp[i].getName();
                }
            }

            if (found == 0){
                anomalies[anomalyCount] = "No names "
                        + "for " + decadeYear + ", rank " 
                        + ranks + ".";
                anomalyCount++;
            }
            else if (found == 1){
                anomalies[anomalyCount] = "One "
                        + "Name (" + tempName + ") for " 
                        + decadeYear + ", rank " 
                        + ranks + ".";
                anomalyCount++;
            }
        }
    }

    writeAnomaliesFile(anomalies);
}

/*
 * Helper method: this method will create and write 
 * each anomalies to a text document called 
 * anomalies.txt. 
 */
private static void 
            writeAnomaliesFile(String[] anomalies) 
            throws FileNotFoundException{
    String fileName = "anomolies.txt";
    PrintWriter outputStream = null;

    outputStream = new PrintWriter(fileName);

    for (int i = 0; i < anomalies.length; i++){
        outputStream.println(anomalies[i]);
    }

    outputStream.close();
}

关于java - 在对象数组中搜索某些值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20341251/

相关文章:

java - 检测 HTML 页面之间的差异百分比

javascript - 如何解决nodejs javascript中的 `...`错误

excel - 用于隐藏行的慢速 VBA 循环

php - 获取数组的第一个值

Java 进程优先于其他 Windows 进程

java - 如何在postgreSQL数据库中存储ISO/IEC 19794-2指纹模板

java - 注解处理第三方库

javascript - Array.every 返回 false 而不是 true

java - 查找数组中数字的位置并给出点,Java

PHP循环遍历JSON多维数组并在单击按钮时加载数据