大家好,所以我被困在这项计划的最后一部分,我一直在做的任务。因此,一般来说,我会获得一个名单和数字的大量列表,这些名称和数字代表了几十年来名字的受欢This is what the file looks like< -----这是一个链接,可以看到names.txt
所以我创建了一个方法,在某个十年内对列表进行排序,即getIndexOfSmallest和交换。每十年有两个名称排名相同所以在1900-1909年间有两个名称排名第一,两个名称排名第2,两个名称排名第3,依此类推。程序的最后一部分和我需要帮助的部分是假设对对象数组进行排序,并找到任何几十年,其中一个等级只有一个名称或某个等级没有名称。输出将被发送到一个文件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++;
}
}
}
}
答案 0 :(得分:0)
解决了我自己不得不睡在它身上:
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();
}