How do I retrieve the length of individual Strings in a set? - java

In my current assignment, I have a text file that contains a large number of words which is stored in a List. one of my methods must store all words of a certain (user specified) length from this List into a Set. furthermore, the different lists are placed into two different classes. My question is: How do I retrieve the length of Individual elements in that list? EDIT: here are the complete classes.
File and List are set up like this in the client class, HangmanMain:
// Class HangmanMain is the driver program for the Hangman program. It reads a
// dictionary of words to be used during the game and then plays a game with
// the user. This is a cheating version of hangman that delays picking a word
// to keep its options open. You can change the setting for SHOW_COUNT to see
// how many options are still left on each turn.
import java.util.*;
import java.io.*;
public class HangmanMain {
public static final String DICTIONARY_FILE = "E:/CSC143/Workspace/Assignment2/src/dictionary.txt";
public static final boolean DEBUG = false; // show words left
public static void main(String[] args) throws FileNotFoundException {
System.out.println("Welcome to the cse143 hangman game.");
System.out.println();
// open the dictionary file and read dictionary into an ArrayList
Scanner input = new Scanner(new File(DICTIONARY_FILE));
List<String> dictionary = new ArrayList<String>();
while (input.hasNext()) {
dictionary.add(input.next().toLowerCase());
}
// set basic parameters
Scanner console = new Scanner(System.in);
System.out.print("What length word do you want to use? ");
int length = console.nextInt();
System.out.print("How many wrong answers allowed? ");
int max = console.nextInt();
System.out.println();
// set up the HangmanManager and start the game
List<String> dictionary2 = Collections.unmodifiableList(dictionary);
HangmanManager hangman = new HangmanManager(dictionary2, length, max);
if (hangman.words().isEmpty()) {
System.out.println("No words of that length in the dictionary.");
} else {
playGame(console, hangman);
showResults(hangman);
}
}
// Plays one game with the user
public static void playGame(Scanner console, HangmanManager hangman) {
while (hangman.guessesLeft() > 0 && hangman.pattern().contains("-")) {
System.out.println("guesses : " + hangman.guessesLeft());
if (DEBUG) {
System.out.println(hangman.words().size() + " words left: "+ hangman.words());
}
System.out.println("guessed : " + hangman.guesses());
System.out.println("current : " + hangman.pattern());
System.out.print("Your guess? ");
char ch = console.next().toLowerCase().charAt(0);
if (hangman.guesses().contains(ch)) {
System.out.println("You already guessed that");
} else {
int count = hangman.record(ch);
if (count == 0) {
System.out.println("Sorry, there are no " + ch + "'s");
} else if (count == 1) {
System.out.println("Yes, there is one " + ch);
} else {
System.out.println("Yes, there are " + count + " " + ch+ "'s");
}
}
System.out.println();
}
}
// reports the results of the game, including showing the answer
public static void showResults(HangmanManager hangman) {
// if the game is over, the answer is the first word in the list
// of words, so we use an iterator to get it
String answer = hangman.words().iterator().next();
System.out.println("answer = " + answer);
if (hangman.guessesLeft() > 0) {
System.out.println("You beat me");
} else {
System.out.println("Sorry, you lose");
}
}
}
my method is set up as such in the HangmanManager class.
import java.util.*;
import java.io.*;
public class HangmanManager {
private List<String> dictionary;
private int length;
private int max;
private Set<String> w = new HashSet<String>();
private SortedSet<Character> guess;
Integer L1 = new Integer(length);
public HangmanManager (List<String> dictionary, int length, int max){
this.dictionary = dictionary;
this.length = length;
this.max = max;
}
public Set<String> words (){
while (scan.hasNext()){
if (scan.next().equals(L1)){
w.add(scan.next());
}
}
return w;
}
public int guessesLeft(){
return max;
}
public SortedSet <Character> guesses(){
Scanner input = new Scanner (System.in);
return guess;
}
public String pattern(){
return null;
}
public int record (char guess){
return guess;
}
}
the Scan is just a placeholder name. As you can see in the first block, the while loop adds all the strings in the DICTIONARY_FILE in the "dictionary" list. What I want to do in the second block is add all the words of a certain length into the w list but I don't know how to read the file from a completely different class (if that's even possible) and I also don't know how to take the length of each individual element in said file. do you guys have any ideas? or do you need me to upload more info.
PS: the full title of my assignment is "Evil Hangman." From what I've looked up, its a fairly common programming assignment so you should be able to google it and get more info on what I mean.
PSS: don't mind the other methods in HangmanManager. I'm mostly focused on the "Words" method.
Thanks for the help.

Okay, so assuming you have the list with all the words set up, here is some pseudocode to guide you forwards.
for every string in set
check if word is of specified length
if true:
add word to set
if false:
do nothing
String api might have some useful methods for this, especially for determining the length of the string.. :)
About the latter part of your question, it is somewhat hard to answer how to access things in another class without more code to see how it is set up. Generally, you use a getter method to retrieve the field.

Related

How to check user input is part of the array in Java

I wanna ask if this is possible. So I have this program will enter a for loop to get the user input on number of subjects. Then after he will enter the subjects listed in the array as his guide. My goal is that I want to check his subjects if it is really inside the array that I made. I made a program but I don't know where to put the part that the program will check the contents.
My goal:
Enter the corresponding code for the subjects you have chosen: user will input 8
Enter the number of subjects you wish to enroll: be able to type the whole subject name like (MATH6100) Calculus 1
then the program will check if the subjects entered are part of the elements inside the array
UPDATE:
I have made another but the problem is that I don't know where to put the code fragment wherein it will check the contents of the user input for list of subjects he wish to enroll.
Here is the code:
private static void check(String[] arr, String toCheckValue){
boolean test=Arrays.asList(arr).contains(toCheckValue);
System.out.println("Is/Are " + toCheckValue + " present in the array: " + test);
}
public static void main(String[] args){
String arr[]={"(MATH6100) Calculus 1", "(ITE6101) Computer Fundamentals", "(ITE6102) Computer Programming 1", "(GE6100) Understanding the Self", "(GE6106) Purposive Comunication 1", "(ETHNS6101) Euthenics 1", "(PHYED6101) Physical Fitness", "(NSTP6101) National Service Training Program 1"};
Scanner input1=new Scanner(System.in);
System.out.print("\nEnter the number of subjects you wish to enroll: ");
int number_subjects1=input1.nextInt();
String []subjects1=new String[number_subjects1];
//else statement when user exceeds the number of possible number of subjects
if(number_subjects1<=8){
for(int counter=0; counter<number_subjects1; counter++){
System.out.println("Enter the corresponding code for the subjects you have chosen (EX. MATH6100): " + (counter+1));
subjects1[counter]=input1.next();
}
String toCheckValue=subjects1[0];
System.out.println("Array: " +Arrays.toString(arr));
check(arr, toCheckValue);
System.out.println("\nPlease check if these are your preferred subjects:");
for(int counter=0; counter<number_subjects1; counter++){
System.out.println(subjects1[counter]);
}System.out.println("********************************** \n" + "\tNothing Follows");
System.out.print("\nIf you have enter some errors please press Y and refresh the form (Y/N): ");
Scanner character=new Scanner(System.in);
String answer_1subjectserrors=character.nextLine();
System.out.println(answer_1subjectserrors + "Based on your answer, you need to refresh thae page and try again.");
}
}
}
I believe the issue is that you are checking your class course codes against an array which contains both the class code AND the class description.
You ask the user to enter the class code but then you use that code to check for its existence in an array containing both the code & description. The contains in List (collections) is not the same as the contains in String.
I have slightly modified your code so you may get the desired result.
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class SOQuestion {
private static void check(String[] arr, String toCheckValue){
List courses = Arrays.asList(arr);
boolean test=courses.contains(toCheckValue);;
System.out.println("Is/Are " + toCheckValue + " present in the array: " + test);
}
public static void main(String[] args) {
String class_codes_and_descriptions[] = { "(MATH6100) Calculus 1", "(ITE6101) Computer Fundamentals", "(ITE6102) Computer Programming 1",
"(GE6100) Understanding the Self", "(GE6106) Purposive Comunication 1", "(ETHNS6101) Euthenics 1",
"(PHYED6101) Physical Fitness", "(NSTP6101) National Service Training Program 1" };
String class_codes[] = { "MATH6100", "ITE6101", "ITE6102","GE6100", "GE6106", "ETHNS6101","PHYED6101", "NSTP6101" };
Scanner input1 = new Scanner(System.in);
System.out.print("\nEnter the number of subjects you wish to enroll: ");
int number_subjects1 = input1.nextInt();
String[] subjects1 = new String[number_subjects1];
// else statement when user exceeds the number of possible number of subjects
if (number_subjects1 <= 8) {
for (int counter = 0; counter < number_subjects1; counter++) {
System.out.println("Enter the corresponding code for the subjects you have chosen (EX. MATH6100): "
+ (counter + 1));
subjects1[counter] = input1.next();
}
String toCheckValue = subjects1[0];
System.out.println("Array: " + Arrays.toString(class_codes_and_descriptions));
check(class_codes, toCheckValue);
System.out.println("\nPlease check if these are your preferred subjects:");
for (int counter = 0; counter < number_subjects1; counter++) {
System.out.println(subjects1[counter]);
}
System.out.println("********************************** \n" + "\tNothing Follows");
System.out.print("\nIf you have enter some errors please press Y and refresh the form (Y/N): ");
Scanner character = new Scanner(System.in);
String answer_1subjectserrors = character.nextLine();
System.out.println(
answer_1subjectserrors + "Based on your answer, you need to refresh the page and try again.");
}
}
}
When you are debugging always try to break down the statements into steps so you know where the error is. For example instead of boolean test=Arrays.asList(arr).contains(toCheckValue);
break it down to two steps like this :
List courses = Arrays.asList(arr);
boolean test=courses.contains(toCheckValue);
That way you will have an easier time checking for issues.
Second request is to always look at the API. Skim over the API to look at the method that you are using to understand it better.
For example if you are using contains method of List then look up the API here:
https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/List.html#contains(java.lang.Object)
Of course since this is Oracle's Java the explanation is imprecise & not straightforward but it is usually helpful.
I would recommend using a different data structure than plain arrays. Since you are already using List why not use another collections data structure like HashMap?
The original poster may want to look at a slightly refactored and cleaned up version of the code & try to figure out how to check for all courses since that is his next question. I believe that should become obvious with a more refactored code:
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class SOQuestion {
public static String class_codes_and_descriptions[] = { "(MATH6100) Calculus 1", "(ITE6101) Computer Fundamentals", "(ITE6102) Computer Programming 1",
"(GE6100) Understanding the Self", "(GE6106) Purposive Comunication 1", "(ETHNS6101) Euthenics 1",
"(PHYED6101) Physical Fitness", "(NSTP6101) National Service Training Program 1" };
public static String class_codes[] = { "MATH6100", "ITE6101", "ITE6102","GE6100", "GE6106", "ETHNS6101","PHYED6101", "NSTP6101" };
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int desired_number_of_subjects = input_desired_number_of_subjects(input);
String[] desired_subjects = enter_subjects(desired_number_of_subjects, input);
String toCheckValue = desired_subjects[0];
System.out.println("Array: " + Arrays.toString(class_codes_and_descriptions));
check(class_codes, toCheckValue);
pls_confirm_desired_subjects(desired_number_of_subjects, desired_subjects);
System.out.println("********************************** \n" + "\tNothing Follows");
System.out.print("\nIf you have enter some errors please press Y and refresh the form (Y/N): ");
Scanner character = new Scanner(System.in);
String answer_1subjectserrors = character.nextLine();
System.out.println(
answer_1subjectserrors + "Based on your answer, you need to refresh the page and try again.");
}
private static int input_desired_number_of_subjects(Scanner input) {
System.out.print("\nEnter the number of subjects you wish to enroll: ");
int take_number_of_subjects = input.nextInt();
// TODO: else statement when user exceeds the number of possible number of subjects
return take_number_of_subjects;
}
private static String[] enter_subjects(int desired_subjects_count , Scanner input_desired_subjects) {
String[] subjects_totake = new String[desired_subjects_count];
if (desired_subjects_count <= 8) {
for (int counter = 0; counter < desired_subjects_count; counter++) {
System.out.println("Enter the corresponding code for the subjects you have chosen (EX. MATH6100): "
+ (counter + 1));
subjects_totake[counter] = input_desired_subjects.next();
}
}
return subjects_totake;
}
private static void check(String[] arr, String toCheckValue){
List courses = Arrays.asList(arr);
boolean test=courses.contains(toCheckValue);
System.out.println("Is/Are " + toCheckValue + " present in the array: " + test);
}
private static void pls_confirm_desired_subjects(int take_number_of_subjects, String[] take_subjects) {
System.out.println("\nPlease check if these are your preferred subjects:");
for (int counter = 0; counter < take_number_of_subjects; counter++) {
System.out.println(take_subjects[counter]);
}
}
}
I will shortly edit the above but a hint is : you can use a for loop to go over the entered desired_subjects array and do a check on each one of the subjects, perhaps?
The following checks for all the courses (though this is not how I would check the courses)
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class SOQuestion {
public static String class_codes_and_descriptions[] = { "(MATH6100) Calculus 1", "(ITE6101) Computer Fundamentals", "(ITE6102) Computer Programming 1",
"(GE6100) Understanding the Self", "(GE6106) Purposive Comunication 1", "(ETHNS6101) Euthenics 1",
"(PHYED6101) Physical Fitness", "(NSTP6101) National Service Training Program 1" };
public static String class_codes[] = { "MATH6100", "ITE6101", "ITE6102","GE6100", "GE6106", "ETHNS6101","PHYED6101", "NSTP6101" };
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int desired_number_of_subjects = input_desired_number_of_subjects(input);
String[] desired_subjects = enter_subjects(desired_number_of_subjects, input);
check_all_desired_subjects(desired_subjects);
pls_confirm_desired_subjects(desired_number_of_subjects, desired_subjects);
System.out.println("********************************** \n" + "\tNothing Follows");
System.out.print("\nIf you have enter some errors please press Y and refresh the form (Y/N): ");
Scanner character = new Scanner(System.in);
String answer_1subjectserrors = character.nextLine();
System.out.println(
answer_1subjectserrors + "Based on your answer, you need to refresh the page and try again.");
}
private static int input_desired_number_of_subjects(Scanner input) {
System.out.print("\nEnter the number of subjects you wish to enroll: ");
int take_number_of_subjects = input.nextInt();
// TODO: else statement when user exceeds the number of possible number of subjects
return take_number_of_subjects;
}
private static String[] enter_subjects(int desired_subjects_count , Scanner input_desired_subjects) {
String[] subjects_totake = new String[desired_subjects_count];
if (desired_subjects_count <= 8) {
for (int counter = 0; counter < desired_subjects_count; counter++) {
System.out.println("Enter the corresponding code for the subjects you have chosen (EX. MATH6100): "
+ (counter + 1));
subjects_totake[counter] = input_desired_subjects.next();
}
}
return subjects_totake;
}
private static void check_all_desired_subjects(String[] desired_subjects) {
System.out.println("Array: " + Arrays.toString(class_codes_and_descriptions));
for (String subject_code_to_check:desired_subjects ) {
check(class_codes, subject_code_to_check);
}
}
private static void check(String[] arr, String toCheckValue){
List courses = Arrays.asList(arr);
boolean test=courses.contains(toCheckValue);
System.out.println("Is/Are " + toCheckValue + " present in the array: " + test);
}
private static void pls_confirm_desired_subjects(int take_number_of_subjects, String[] take_subjects) {
System.out.println("\nPlease check if these are your preferred subjects:");
for (int counter = 0; counter < take_number_of_subjects; counter++) {
System.out.println(take_subjects[counter]);
}
}
}

Output will not print the correct information

I'm trying to make a program which asks the user a particular bird then how many of them they had seen at that point. If the use at any point enters the word 'END' then the system should print out the most seen bird and the number seen. However, when running my program if I enter 'END' at random points it instead returns that the most seen was END with 0 seen. I can't figure out how to make it work. I've tried different methods but it's just not working properly. Also, I've set the maximum array limit to 10 possitions but it continues after 10 and if i enter a value the system crashes. Have I written the limit part properly? Or am I missing something important?
import java.util.Scanner;
public class testing
{
public static void main (String[] param)
{
birdInput();
most();
System.exit(0);
}
public static void birdInput()
{
int i = 0;
String birdInput;
int numberInput;
Scanner scanner = new Scanner(System.in);
int maxVal = Integer.MIN_VALUE;
int maxValIndex = -1;
while (true)
{
System.out.println("What bird did you see?");
birdInput = scanner.nextLine();
if (birdInput.equals("END"))
{
System.out.print("\nWell....I guess thanks for using this program?\n");
System.exit(0);
}
else
{
String[] birds = new String[10];
int[] numbers = new int[10];
birds[i] = scanner.nextLine();
System.out.println("How many did you see?");
numbers[i] = scanner.nextInt();
i++;
if (birds[i].equals("END"))
{
maxVal = numbers[i];
maxValIndex = i;
System.out.print("\nThe most common bird that you saw was the " + birds[maxValIndex] + " with " + maxVal + " being seen in total\n");
System.exit(0);
}
}
}
}
public static void most()
{
System.out.println("fdff");
}
}
This is my edit of Till Hemmerich's answer to my issue. I tried to remove the global variables and so combine the entire code into 1 method. However, I'm still having some issues. Been working at it but really confused.
import java.util.Scanner;
public class birds2
{
public static void main(String[] param)
{
birdInput();
System.exit(0);
}
public static void birdInput()
{
Scanner scanner = new Scanner(System.in);
String[] birds = new String[99999999];
int[] numbers = new int[99999999];
int i = 0;
int maxIndex;
while (i <= birds.length)
{
System.out.println("What bird did you see?");
birds[i] = scanner.nextLine();
System.out.println("How many did you see?");
numbers[i] = scanner.nextInt();
i++;
}
int newnumber = numbers[i];
if ((newnumber > numbers.length))
{
maxIndex = i;
i++;
}
if (birds[i].toUpperCase().equals("END"))
{
System.out.print("\nWell....I guess thanks for using this program?\n");
System.out.print("\nThe most common bird that you saw was the " + birds[maxIndex] + " with " + numbers[maxIndex] + " being seen in total\n");
System.exit(0);
}
}
}
You're re-declaring the birds and numbers arrays in each iteration of the loop. They should be declared and initialized only once, before the loop.
I changed a lot so im going to explain my changes here in total.
First of all i had to move the Array Definition out of your while-loop as >mentioned above, since other wise you would override these Arrays every time.
I also made them globally accessible to work with them in other methods.
public static int maxIndex;
public static String[] birds = new String[10];
public static int[] numbers = new int[10];
in general I re structured the whole code a little bit to make it more readable and a little bit more object-orientated.
For example I created an method called inputCheck() which returns our input as a String and check if it equals END so you do not have to write your logic for this twice. (it also considers writing end lower or Uppercased by just Upper our input before checking it"if (input.toUpperCase().equals("END"))")
static String inputCheck() {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
if (input.toUpperCase().equals("END")) {
end();
}
return input;
}
this method can now be called every time you need an input like this:
birds[i] = inputCheck();
but you need to be carefull if you want to get an integer out of it you first have to parse it like this:Integer.parseInt(inputCheck())
after that I wrote a method to search for the biggest Value in your numbers Array and getting its index:
public static int getMaxIndex(int[] numbers) {
for (int i = 0; i < numbers.length; i++) {
int newnumber = numbers[i];
if ((newnumber > numbers.length)) {
maxIndex = i;
}
}
return maxIndex;
}
it takes an int array as parameter and returns the index of the highest element in there as an Integer. Called like this:maxIndex = getMaxIndex(numbers);
Then after that I rewrote your end method. It now just calles our getMaxIndex method and prints some output to the console.
public static void end() {
maxIndex = getMaxIndex(numbers);
System.out.print("\nWell....I guess thanks for using this program?\n");
System.out.print("\nThe most common bird that you saw was the " + birds[maxIndex] + " with " + numbers[maxIndex] + " being seen in total\n");
System.exit(0);
}
to fix your last problem (crashing after more then 10 inputs)I changed your while-loop. Since your array only has 10 places to put things it crashes if you try to put information in place number 11. it not looks like this:while (i <= birds.length) instead of while (true) this way the max loops it can take is the amout of places Array birds has and it wont crash anymore.
public static void birdInput() {
int i = 0;
while (i <= birds.length) {
System.out.println("What bird did you see?");
birds[i] = inputCheck();
System.out.println("How many did you see?");
numbers[i] = Integer.parseInt(inputCheck()); //you should check here if its actuall a number otherwiese your programm will crash
i++;
}
}
Here is the whole code in total:
import java.util.Scanner;
/**
*
* #author E0268617
*/
public class JavaApplication1 {
public static int maxIndex;
public static String[] birds = new String[10];
public static int[] numbers = new int[10];
public static void main(String[] param) {
birdInput();
most();
System.exit(0);
}
public static void birdInput() {
int i = 0;
while (i <= birds.length) {
System.out.println("What bird did you see?");
birds[i] = inputCheck();
System.out.println("How many did you see?");
numbers[i] = Integer.parseInt(inputCheck()); //you should check here if its actuall a number otherwiese your programm will crash
i++;
}
}
static String inputCheck() {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
if (input.toUpperCase().equals("END")) {
end();
}
return input;
}
public static int getMaxIndex(int[] numbers) {
for (int i = 0; i < numbers.length; i++) {
int newnumber = numbers[i];
if ((newnumber > numbers.length)) {
maxIndex = i;
}
}
return maxIndex;
}
public static void end() {
maxIndex = getMaxIndex(numbers);
System.out.print("\nWell....I guess thanks for using this program?\n");
System.out.print("\nThe most common bird that you saw was the " + birds[maxIndex] + " with " + numbers[maxIndex] + " being seen in total\n");
System.exit(0);
}
public static void most() {
System.out.println("fdff");
}
}
I hope you understand where the Problems had been hidden if you have any Questions hit me up.

I'm having a few errors - Java program [duplicate]

This question already has answers here:
What does a "Cannot find symbol" or "Cannot resolve symbol" error mean?
(18 answers)
Closed 5 years ago.
This is really odd, I wrote a class for this program and was about to test how it reads data in from the file but I'm getting a "Cannot find symbol" error that refers to the "new" in the first scanner declared. The same error for the "=" in the second Scanner variable, and a bunch of cannot find symbols for all the "Candidate_Info[i]" objects later on. I dunno where my error is. I'm using notepad++ by the way, compiling and running it using notepad++ too.
import java.util.Scanner; //I'm only gonna need scanner for this project I think
import java.io.*;
public class HuntowskiSamuel //This is what the file name should be as well as the class name
{
public static void main (String [] args) throws IOException
{
File CFile = new File("cipcs115.txt"); //This will be the file and scanner variable used to pull the data for the candidates
Scanner scan = new Scanner(Cfile);
File CfileReadIn = new File("cipcs115.txt"); //While this file and scanner will be used to pull the number of candidates from the same file...hopefully
Scanner scanReadIn = new Scanner(CFileReadIn);
String StateName = "No name yet"; //This is where the state value will be held, that controls the input of the file
int NumberOfCandidates = 0; // This will pull the number of candidates for the array size
String garbage = "Empty"; //This is where the ReadIn scanner can dump excess stuff
StateName = scanReadIn.next(); //The prime read for the while loop
int NumberOfLettersEntered [] = new int [8]; //Since we only have the letters L, C, V, S, D, P, Q, and X (others/errors) that were entered, IN THAT ORDER. Its not graceful but it works
while(StateName != "END_OF_FILE") //While we haven't reached the end of the file
{
for(int i = scanReadIn.nextInt(); i > 0; i--) //Read in the number of candidates, then run the loop that number of times
{
NumberOfCandidates++; //Every time this loop runs, it means there is one more candidate for the total amount
garbage = scanReadIn.nextLine(); //This will take all the important info and dump it, seeing as we only need the number of candidates and the state name
}
StateName = scanReadIn.next(); //Pull the next state name
}
Candidate_Info Candidates [] = new Candidate_Info [NumberOfCandidates]; //This creates an array of the exact size of the number of candidates in the file
for(int i = 0; i < NumberOfCandidates; i++) //Running the constructor for each and every candidate created
{
Candidate_Info [i] = Candidate_Info();
}
StateName = scan.next(); //Prime read for the data taking loop
while(StateName != "END_OF_FILE") //The same as the other loop, only using the real file and scanner variables
{
int CandidateNumber = 0; //This will keep the array number straight from 0 to however many candidates - 1
for(int i = 0; i < scan.nextInt(); i++) //This will loop for each of the candidates in ONE STATE, it pulls the number of candidates as an int
{
Candidate_Info[CandidateNumber].setState(StateName);
Candidate_Info[CandidateNumber].setName(scan.next());
Candidate_Info[CandidateNumber].setOffice(scan.next());
Candidate_Info[CandidateNumber].setParty(scan.next().charAt(0)); //This might not work because it is just a single character versus the string that it would be passed
Candidate_Info[CandidateNumber].setVotes(scan.nextInt());
Candidate_Info[CandidateNumber].setSpent(scan.nextDouble());
Candidate_Info[CandidateNumber].setMotto(scan.nextLine());
CandidateNumber++;
}
StateName = scan.next();
}
}
}
And here's the code for the Class I wrote.
//Samuel James Huntowski
// started: 11-18-2014
// last modified: 11-18-2014
public class Candidate_Info
{
private String State; //All the variables that were given to me in the specification
private String Name_of_Candidate;
private String Election_Office;
private char Party;
private int Number_of_Votes;
private double Dollars_Spent;
private String Motto;
private final double DOLLARS_SPENT_MIN = 0.0; //Mutator method for Dollars_Spent must check to see if greater then this value
private final int NUMBER_OF_ATTRIBUTES = 7; //for use in the equals method
public Candidate_Info()
{
State = "No state assigned"; //Giving empty values to all of the variables
Name_of_Candidate = "No name yet";
Election_Office = "No office assigned";
Party = 'X';
Number_of_Votes = 0;
Dollars_Spent = 0.0;
Motto = "No motto yet";
}
//These are all of the Accessor Methods
public String getState()
{
return State;
}
public String getName()
{
return Name_of_Candidate;
}
public String getOffice()
{
return Election_Office;
}
public char getParty()
{
return Party;
}
public int getVotes()
{
return Number_of_Votes;
}
public double getSpent()
{
return Dollars_Spent;
}
public String getMotto()
{
return Motto;
}
//Mutator methods will go here
public void setState(String newState)
{
State = newState;
System.out.println("The candidate's state is now set to " + newState + ".");
}
public void setName(String newName)
{
Name_of_Candidate = newName;
System.out.println("The candidate's name is now set to " + newName + ".");
}
public void setOffice(String newOffice)
{
Election_Office = newOffice;
System.out.println("The candidate's office is now set to " + newOffice + ".");
}
public void setParty(char newParty)
{
if(!((newParty == 'd') || (newParty == 'r') || (newParty == 'i') || (newParty == 'o'))) //If the value of newParty DOES NOT EQUAL 'o', 'd', 'r', or 'i' then do the next set of code
{
System.out.println("Invalid party input. Candidate's party remains unchanged. Please try again.");
}
else
{
Party = newParty;
System.out.println("The candidate's party is now set to " + newParty + ".");
}
}
public void setVotes(int newNumberOfVotes)
{
Number_of_Votes = newNumberOfVotes;
System.out.println("The candidate's number of votes is now set to " + newNumberOfVotes + ".");
}
public void setSpent(double newDollarsSpent)
{
if(newDollarsSpent < DOLLARS_SPENT_MIN) //If the amount of money spent is less then zero (Which just wouldn't make sense, so that's why I set the variable to zero)
{
System.out.println("New amount of dollars spent is invalid. Candidate's dollars spent remains unchanged. Please try again.");
}
else
{
Dollars_Spent = newDollarsSpent;
System.out.println("The candidate's dollars spent is now set to " + newDollarsSpent + ".");
}
}
public void setMotto(String newMotto)
{
Motto = newMotto;
System.out.println("The candidate's motto is now set to \"" + newMotto + "\"");
}
public void displayAll()
{
System.out.println(State + "\t" + Name_of_Candidate + "\t"
+ Election_Office + "\t" +
Party + "\t" + Number_of_Votes +
"\t" + Dollars_Spent + "\t" + Motto); //Display all info separated by tabs
}
public String toString()
{
String ReturnThis = (State + "\t" + Name_of_Candidate + "\t" +
Election_Office + "\t" + Party +
"\t" + Number_of_Votes + "\t" +
Dollars_Spent + "\t" + Motto); //same as displayAll() just in one string
return ReturnThis;
}
public boolean equals(Candidate_Info PassedCandidate)
{
boolean TF [] = new boolean [NUMBER_OF_ATTRIBUTES]; //An array of booleans that match the number of attributes above
boolean finalResult; //This will hold the final boolean result of all the below calculations
if(State.equals(PassedCandidate.getState())) TF[0] = true; //This isn't the most graceful method of doing this, but it works
else TF[0] = false;
if(Name_of_Candidate.equals(PassedCandidate.getName())) TF[1] = true;
else TF[1] = false;
if(Election_Office.equals(PassedCandidate.getOffice())) TF[2] = true;
else TF[2] = false;
if(Party == PassedCandidate.getParty()) TF[3] = true;
else TF[3] = false;
if(Number_of_Votes == PassedCandidate.getVotes()) TF[4] = true;
else TF[4] = false;
if(Dollars_Spent == PassedCandidate.getSpent()) TF[5] = true;
else TF[5] = false;
if(Motto.equals(PassedCandidate.getMotto())) TF[6] = true;
else TF[6] = false;
if(TF[0] && TF[1] && TF[2] && TF[3] && TF[4] && TF[5] && TF[6]) finalResult = true; //If ALL OF THE ATTRIBUTES equal the attributes of the passed candidate, therefore making all the TF variables true, then they are equal
else finalResult = false;
return finalResult;
}
}
Samuel, try and use the "camelCase" naming convention where the first letter of a variable name is lowercase, not uppercase. Only classes should get uppercase first letters. That lets you easily identify whether something is a class or a variable.
Not doing this has already resulted in a small mistake in the beginning of your code, where you accidentally refer to the CFile variable as Cfile, which Java will interpret as two different things. This is why you were getting the error about not being able to find the symbol, because Java didn't know what Cfile was, only CFile.
I also took a look lower in your code. You create a candidates variable, but then accidentally keep referring to it by its class Candidate_Info in the for and while loops.
To construct a new object out of a class, you must put the new keyword before it. You cannot just directly reference the constructor method as you did in the for loop.
Here's a version that may better show what I mean:
import java.util.Scanner; //I'm only gonna need scanner for this project I think
import java.io.*;
public class HuntowskiSamuel //This is what the file name should be as well as the class name
{
public static void main (String [] args) throws IOException
{
File cFile = new File("cipcs115.txt"); //This will be the file and scanner variable used to pull the data for the candidates
Scanner scan = new Scanner(cFile);
File cFileReadIn = new File("cipcs115.txt"); //While this file and scanner will be used to pull the number of candidates from the same file...hopefully
Scanner scanReadIn = new Scanner(cFileReadIn);
String stateName = "No name yet"; //This is where the state value will be held, that controls the input of the file
int numberOfCandidates = 0; // This will pull the number of candidates for the array size
String garbage = "Empty"; //This is where the ReadIn scanner can dump excess stuff
stateName = scanReadIn.next(); //The prime read for the while loop
int numberOfLettersEntered [] = new int [8]; //Since we only have the letters L, C, V, S, D, P, Q, and X (others/errors) that were entered, IN THAT ORDER. Its not graceful but it works
while(stateName != "END_OF_FILE") //While we haven't reached the end of the file
{
for(int i = scanReadIn.nextInt(); i > 0; i--) //Read in the number of candidates, then run the loop that number of times
{
numberOfCandidates++; //Every time this loop runs, it means there is one more candidate for the total amount
garbage = scanReadIn.nextLine(); //This will take all the important info and dump it, seeing as we only need the number of candidates and the state name
}
stateName = scanReadIn.next(); //Pull the next state name
}
Candidate_Info candidates [] = new Candidate_Info [numberOfCandidates]; //This creates an array of the exact size of the number of candidates in the file
for(int i = 0; i < numberOfCandidates; i++) //Running the constructor for each and every candidate created
{
candidates[i] = new Candidate_Info();
}
stateName = scan.next(); //Prime read for the data taking loop
while(stateName != "END_OF_FILE") //The same as the other loop, only using the real file and scanner variables
{
int candidateNumber = 0; //This will keep the array number straight from 0 to however many candidates - 1
for(int i = 0; i < scan.nextInt(); i++) //This will loop for each of the candidates in ONE STATE, it pulls the number of candidates as an int
{
candidates[candidateNumber].setState(stateName);
candidates[candidateNumber].setName(scan.next());
candidates[candidateNumber].setOffice(scan.next());
candidates[candidateNumber].setParty(scan.next().charAt(0)); //This might not work because it is just a single character versus the string that it would be passed
candidates[candidateNumber].setVotes(scan.nextInt());
candidates[candidateNumber].setSpent(scan.nextDouble());
candidates[candidateNumber].setMotto(scan.nextLine());
candidateNumber++;
}
stateName = scan.next();
}
}
}
Note that without your text files, it's going to be hard to determine how your code will actually work, but I just wanted to warn you about a common problem with Scanner when you mix nextInt with nextLine. See this.

Coin flip game save issue

I am creating a coin flip game for an assignment that saves your last high score and name. the program works fine if there is not a high score file already there, but if there is a file there the program stops working.
import java.util.Scanner;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
public class BradySkuza43
{
public static void main( String[] args ) throws Exception
{
Scanner keyboard = new Scanner(System.in);
String coin, again, bestName, saveFile = "coin-flip-score.txt";
int flip, streak = 0, best;
File in = new File(saveFile);
if ( in.createNewFile() )
{
System.out.println("Save game file doesn't exist. Created.");
best = 1;
bestName = " ";
}
else
{
Scanner input = new Scanner(in);
bestName = input.next();
best = input.nextInt();
input.close();
System.out.println("High score is " + best + " flips in a row by " + bestName );
}
do
{
flip = 1 + (int)(Math.random()*2);
if ( flip == 1 )
{
coin = "HEADS";
}
else
{
coin = "TAILS";
}
System.out.println( "You flip a coin and it is... " + coin );
if ( flip == 1 )
{
streak++;
System.out.println( "\tThat's " + streak + " in a row...." );
System.out.print( "\tWould you like to flip again (y/n)? " );
again = keyboard.next();
}
else
{
streak = 0;
again = "n";
}
} while ( again.equals("y") );
System.out.println( "Final score: " + streak );
if ( streak > best )
{
System.out.println("That's a new high score!");
System.out.print("Your name: ");
bestName = keyboard.next();
best = streak;
}
else if ( streak == best )
{
System.out.println("That ties the high score. Cool.");
}
else
{
System.out.println("You'll have to do better than " + streak + "if you want a high score.");
}
PrintWriter out = new PrintWriter( new FileWriter(saveFile) );
out.println(bestName);
out.println(best);
out.close();
}
}
when there is a file already there I get a NoSuchElement error. I am assuming it has to do with the import functions but I am unaware of how to fix it.
The way you read 'best' when there is already a file (with the 'best' value) seems to be incorrect. You may be looking for something like this (modify based on your data) to read the 'saved best value'.
BufferedReader reader = new BufferedReader(new FileReader(in));
String readNumber = "";
while (reader.readLine() != null) {
readNumber += reader.readLine();
}
best = Integer.valueOf(readNumber);
Ended up having to just run the code to see how the savefile is being produced. Seeing that NoSuchElement exception is coming from the second read from the file (input.nextInt()) pointed to the problem.
If you don't beat the existing the streak (including getting TAILS as your first flip), you aren't prompted for a name. This makes the savefile read
\n
1
\n
Scanner by default ignore whitespace. You don't check if there is available input (hasNext methods). When you call the next() or nextInt() when there is no input you get NoSuchElement. Why is this happening from the save?
Line by line:
bestName = input.next(); <-- This is getting the "1" since there is a name saved
best = input.nextInt(); <-- since the 1 was already read, so there's nothing to get
That second input with the savefile after getting an initial TAILS, is causing your crash.
Two solutions, make sure you are getting and saving the bestName in the else at the end of your main, or be more careful in reading the savefile.
(edit)
In general when using Scanner (or just about anything API that has a the hasNext()/next() style), it's best to call and check hasNext() before each next(). This will ensure you have something to get from the next().
Even if you don't think there is a possible reason for there not to be something there, having something like
if(!foo.hasNext) {
System.out.println("foo should really have something here, but hasNext says it doesn't);
System.exit();
}
will stop your code in its tracks if there is a problem, and give you a stop to add some debug statements to see what's going on.
Here are some suggestions:
Your high score file's name doesn't change, right? It shouldn't be a variable, it should be a static final variable.
Play the game and then decide whether or not this is a high score. So you should have a getHighScore() method (which can be static).
If the new score is a high score, then write it to the high score file. There should be a method static writeHighScore(final String name, final int score).
So I would change your program to something more like this:
public class BradySkuza43
{
public static final String HIGH_SCORE_FILE = "coin-flip-score.txt";
public static void main( String[] args ) throws Exception
{
final Scanner keyboard = new Scanner(System.in);
final int highScore = getHighScore();
final int newScore = getScore(keyboard);
if(newScore != 0 && newScore > highScore){
final String name = getName(keyboard);
writeHighScore(name, newScore);
}
private static int highScore(){
// read high score from high score file or return Integer.MIN_VALUE if
// no high score file exists
}
private static int getScore(final Scanner keyboard){
// play game, prompt user, get input, etc. and then
// return the player's score.
}
private static String getName(final Scanner keyboard){
// prompt the user for their name and return their input
}
private static void writeHighScore(final String name, final int score){
// write this high score (with the name) to the high score file
}
}

Counting the occurrence of objects in an ArrayList, using either Collections or my functions

I have an ArrayList of FlowerClass objects. Each of these FlowerClass objects has a name. I want to go through the ArrayList and count them. I want to display the amount of each. So if I have three FlowerClass objects named Rose, two named Daffodil, and one named Tulip...I want to display the following:
Found 3 Rose
Found 3 Daffodil
Found 3 Tulip
So far, I've gotten it to count correctly using two functions I made. The problem is that I iterate through the entire ArrayList...so it'll show me the results more than once. For example, if the user adds 3 Roses and 2 Daffodils...The output is like this:
Found 3 Roses
Found 3 Roses
Found 3 Roses
Found 2 Daffodils
Found 2 Daffodils
I know why the code does this but I don't know how to erase repeats of output. I also don't know how to implement Collections correctly. I've used Collections on an ArrayList of strings before...and it works. But this time I'd be using Collections on an ArrayList of Objects, and I want to check for the frequency of each specific name. Here is the main class:
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
public class MainClass {
static ArrayList<FlowerClass> flowerPack = new ArrayList<FlowerClass>();
public static void main(String[] args){
Scanner input = new Scanner(System.in);
while(true){
System.out.println("1. Add flower to flowerpack.");
System.out.println("2. Remove flower from the flowerpack.");
System.out.println("3. Search for a flower in the flowerpack.");
System.out.println("4. Display the flowers in the flowerpack.");
System.out.println("5. Exit the program.");
int userChoice = input.nextInt();
switch(userChoice){
case 1:
addFlower();
break;
case 2:
searchFlower();
break;
case 3:
displayFlowers();
break;
case 4:
System.out.println("Goodbye!");
System.exit(0);
}
}
}
public static void addFlower(){
if (FlowerClass.numberFlowers() == 25){
System.out.println("There are 25 flowers in the flowerpack. Remove at least one in order to add more.");
return;
}
Scanner input = new Scanner(System.in);
System.out.println("What is the flower's name?");
String desiredName = input.nextLine();
System.out.println("What is the flower's color?");
String desiredColor = input.nextLine();
System.out.println("How many thorns does it have?");
Scanner input2 = new Scanner(System.in);
int desiredThorns = input2.nextInt();
System.out.println("What does it smell like?");
String desiredSmell = input.nextLine();
flowerPack.add(new FlowerClass(desiredName, desiredColor, desiredThorns, desiredSmell));
}
public static void searchFlower(){
System.out.println("Enter the flower you want to search for.");
Scanner input = new Scanner(System.in);
String userChoice = input.nextLine();
int occurrences = 0;
for (FlowerClass flower: flowerPack){
String name = flower.getName();
if (userChoice.equals(name)){
occurrences++;
}
else if(occurrences == 0){
System.out.println("Match not found.");
return;
}
}
System.out.println("Found " + occurrences + " " + userChoice);
}
public static void searchFlower(String desiredFlower){
int occurrences = 0;
String userChoice = desiredFlower;
for (FlowerClass flower: flowerPack){
String name = flower.getName();
if (userChoice.equals(name)){
occurrences++;
}
}
System.out.println("Found " + occurrences + " " + userChoice);
}
public static void displayFlowers(){
int repeats = 0;
/*for (FlowerClass flower: flowerPack){
System.out.println(flower.getName());
}
System.out.println("Number of flowers in pack: " + FlowerClass.numberFlowers());*/
//int occurrences = Collections.frequency(flowerPack, name);
//System.out.println(name + ": " + occurrences);
for (FlowerClass flower: flowerPack){
String name = flower.getName();
searchFlower(name);
}
}
}
Here is the FlowerClass:
public class FlowerClass {
public static int numberOfFlowers = 0;
public String flowerName = null;
public String flowerColor = null;
public int numberThorns = 0;
public String flowerSmell = null;
FlowerClass(){
}
FlowerClass(String desiredName, String desiredColor, int desiredThorns, String desiredSmell){
flowerName = desiredName;
flowerColor = desiredColor;
numberThorns = desiredThorns;
flowerSmell = desiredSmell;
numberOfFlowers++;
}
public void setName(String desiredName){
flowerName = desiredName;
}
public String getName(){
return flowerName;
}
public static int numberFlowers(){
return numberOfFlowers;
}
}
If you look at my last function in the main class, you'll see that I commented out the way I was attempting to implement Collections.frequency. I also tried making a multidimensional array of Strings and storing the names of the flowers and also the number of flowers in the arrays. This was counting everything correctly but I wasn't sure how to display the names alongside the counts. It was getting very messy so I abandoned that attempt for now in favor of trying these other two options. If I can find a way to erase repeated lines of output (or if I can find a way to get Collections to work) then I won't need to tinker with the multidimensional array.
Any tips would be very much appreciated. Thank you for your time.
Interesting code, but it doesn't work the way I would do it.
In this current case as you've done it, you would need to keep track of the flower names you have already encountered:
public static void displayFlowers(){
//int repeats = 0;
List<String> displayedFlowerTypes = new ArrayList<String>();
for (FlowerClass flower: flowerPack){
String name = flower.getName();
if(!displayedFlowerTypes.contains(name))
{
displayedFlowerTypes.add(name);
searchFlower(name);
}
}
}
What I would rather do is maintain a Map that keeps track of the counts of the flower types, and just obtain the numbers for the types from that:
public class MainClass {
static List<FlowerClass> flowerPack = new ArrayList<FlowerClass>();
static Map<String, Integer> flowerCount = new HashMap<String, Integer>();
public static void addFlower() {
if (FlowerClass.numberFlowers() == 25) {
System.out.println("There are 25 flowers in the flowerpack. Remove at least one in order to add more.");
return;
}
Scanner input = new Scanner(System.in);
System.out.println("What is the flower's name?");
String desiredName = input.nextLine();
System.out.println("What is the flower's color?");
String desiredColor = input.nextLine();
System.out.println("How many thorns does it have?");
Scanner input2 = new Scanner(System.in);
int desiredThorns = input2.nextInt();
System.out.println("What does it smell like?");
String desiredSmell = input.nextLine();
flowerPack.add(new FlowerClass(desiredName, desiredColor, desiredThorns, desiredSmell));
if(!flowerCount.containsKey(desiredName))
{
flowerCount.put(desiredName, 1);
}
else
{
int currentCount = flowerCount.get(desiredName);
flowerCount.put(desiredName, currentCount+1));
}
}
That way, you could just display the flowers as the following:
public static void displayFlowers() {
for (String name : flowerCount.keySet()) {
//searchFlower(name);
System.out.println("Found " + flowerCount.get(name) + " " + name);
}
}
You could put your Flower(s) in a Set. But the easiest solution I can think of is to sort your flowers. So first, implement a Comparator<FlowerClass>
public static class FlowerComparator implements Comparator<FlowerClass> {
#Override
public int compare(FlowerClass o1, FlowerClass o2) {
return o1.getName().compareTo(o2.getName());
}
}
Then you can sort with Collections.sort(List, Comparator)
FlowerComparator flowerComparator = new FlowerComparator();
Collections.sort(flowerPack, flowerComparator);
And then your for loop needs to be something like this (to stop searching for the same flower),
String lastName = null;
for (int i = 0; i < flowerPack.size(); i++){
FlowerClass flower = flowerPack.get(i);
String name = flower.getName();
if (lastName == null || !lastName.equals(name)) {
lastName = name;
searchFlower(name); // or return the number found, and then add that count to i.
}
}

Categories

Resources