I am working in a small task that allow the user to enter the regions of any country and store them in one array. Also, each time he enters a region, the system will ask him to enter the neighbours of that entered region and store these neighbours.
I did the whole task but I have a small problem:
I could not be able to print each region and its neighbours like the following format:
Region A: neighbour1 neighbour2
Region B: neighbour1 neighbour2
For example, let us take USA map. I want to print the result as following:
Washington D.C: Texas, Florida, Oregon
and so on.
My code is:
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
public class Test7{public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
System.out.print("Please enter the number of regions: ");
int REGION_COUNT = kb.nextInt();
String[] regionNames = new String[REGION_COUNT];
String[][] regions = new String[REGION_COUNT][2];
for (int r = 0; r < regions.length; r++) {
System.out.print("Please enter the name of region #" + (r + 1)
+ ": ");
regionNames[r] = kb.next();
System.out
.print("How many neighbors for region #" + (r + 1) + ": ");
if (kb.hasNextInt()) {
int size = kb.nextInt();
regions[r] = new String[size];
for (int n = 0; n < size; n++) {
System.out.print("Please enter the neighbour #" + (n)
+ ": ");
regions[r][n] = kb.next();
}
} else
System.exit(0);
}
for (int i = 0; i < REGION_COUNT; i++) {
System.out.print(regionNames[i] +": ");
for (int k = 0; k < 2; k++) {
System.out.print(regions[i][k]+", ");
}
System.out.println();
}
}
}
The code works fine but the problem is with printing the result only.
Also, I should use the 2 dimensional array.
As I see it, you think your problem is dealing with a jagged 2-D array. I think your problem is that you're using arrays of strings in the first place. I'd suggest using a class to model your regions and their neighbors rather than an array of strings.
public class Region
{
private String Name;
public void setName( String name ) {
this.Name = name;
}
public String getName() {
return this.Name;
}
private ArrayList<Region> Neighbors;
public void addNeighbor( Region neighbor ) {
...
}
public ArrayList<Region> getNeighbors()
{
...
}
}
Then keep a hash of the known regions, creating new ones as necessary, and use those to populate a region's neighbors as needed. Then you can iterate over the regions in your hash and, for each region, iterate over its neighbors.
This is what you want:
for (int i = 0; i < region.length; i++){
StringBuilder sb = new StringBuilder();
sb.append(region[i] + ": ");
for (int i2 = 0; i2 < neighbor.length; i2++){
if (i2 != 0 && i2 != neighbor.length-1){
sb.append(", " + neighbor[i2]);
}else{
sb.append(neighbor); //it still need a validation of an array of 2 Strings
}
}
System.out.println(sb.toString());
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
how do I pair the student array with the grade array? When I find the highest grade the corresponding student should also show, and same with the lowest graded student. I cant figure out how to make this program perform as such with two separate arrays.
import java.util.Scanner;
public class Asm7 {
public static void main(String[] args) {
Scanner Scan = new Scanner(System.in);
System.out.println("How many students do you have?: ");
int AMOUNT = 0;
AMOUNT = Scan.nextInt();
String[] STUDENT = new String [AMOUNT];
int COUNTER = 0;
int GRADE [] = new int [AMOUNT];
if (AMOUNT <= 0) {
System.out.println("Invalid student amount");
}
else {
for(int i = 0; i < AMOUNT; i++){
System.out.println("Enter student's first name: " + (i+1));
STUDENT[i] = Scan.next();
System.out.println("Enter student's grade in order added: ");
GRADE[i] = Scan.nextInt();
}
for(int i = 0; i < AMOUNT; i++){
System.out.println(STUDENT[i] + " received the final grade of " + GRADE[i]);}
System.out.println();
int [] Results = MinMax(GRADE);
System.out.println("The highest grade in the class was " + Results[1]);
System.out.println("The lowest grade in the class was "+ Results[0]);
}}
public static int[] MinMax(int[] value) {
int[] Result = new int[]{Integer.MAX_VALUE, Integer.MIN_VALUE};
for (int i : value) {
Result[0] = i < Result[0] ? i : Result[0];
Result[1] = i > Result[1] ? i : Result[1];
}
return Result;
}
}
Your while loop validation for number of students is a little late. You want to do this before you declare and initialize your arrays. However, the fact that the while loop was actually used in an attempt towards some form of validation is a really good sign. It's more than most new programmers tend to do. All input should be validated and provide a User the opportunity to supply a correct solution. This can only lead to a smoother, trouble free application and a much better experience for the User. Take a look at this while loop which is in your code:
while (amount < 0) {
System.out.println("Invalid student amount");
}
What is going to happen if the User supplies -1 (this is a valid integer value as is +1)? That's right...your application will end up in an infinite loop spitting out Invalid student amount to the Console Window. Your validation scheme should encompass the entire prompt and then the means to exit it should be more logically defined. With a while loop the best exit is done through its conditional statement, if the condition is false then exit the loop, for example:
Scanner scan = new Scanner(System.in);
// Number Of Students...
String inputString = "";
while (inputString.isEmpty()) {
System.out.print("How many students do you have?: --> ");
inputString = scan.nextLine().trim();
/* Is the supplied Number Of Students valid and within
range (1 to 50 inclusive)? */
if (!inputString.matches("\\d+") || Integer.valueOf(inputString) < 1
|| Integer.valueOf(inputString) > 50) {
// No...
System.err.println("Invalid entry (" + inputString + ") for Student "
+ "amount! Try again...");
inputString = ""; // Empty inputString so we loop again.
System.out.println();
}
}
// Valid amount provided.
int amount = Integer.valueOf(inputString);
String[] student = new String[amount];
int grade[] = new int[amount];
Right away you will notice some obvious changes here. The entire How many students do you have? prompt is contained within a while loop block. If the User does not supply a valid response then that User is asked to try again. The student and grade parallel arrays are declared and initialized only after a valid response for the number of students is provided.
You will also notice that the while loop condition doesn't rely on a integer value but instead it relies on actual string content (regardless of what it is) instead. If the variable is empty ("") then loop again. This is because the Scanner#nextLine() method is used to collect the Users input instead of the Scanner#nextInt() method. The prompt still expects an integer value to be supplied, just a string representation of an integer value and this is validated using the String#matches() method along with a small Regular Expression (regex).
I personally prefer to use the Scanner#nextLine() method for a number of reasons. I personally find it more flexible especially if you want to accept both Alpha and Numerical input from a single prompt. If the prompt above stated:
How many students do you have? (q to quit)
you would just need to add another if statement above the numerical validation code to see if 'q' or 'Q' was supplied, for example:
// If either q or Q is entered then quit application.
if (amountString.matches("[qQ]")) {
System.out.println("Bye-Bye");
System.exit(0);
}
Also, with a good expression passed to the matches() method, there is no need to trap exceptions in order to carry out validations, not that there is anything wrong with this, many people do it, I especially don't however when I have no need to do so.
Side Note: I'm going to state the obvious here and I'm sure you've heard it a hundred times before and you're sick of hearing it but I'm going to tell you again:
Your class methods should start with a lowercase letter (see Java Naming
Conventions).
I know you don't hear the compiler complaining but it does make it a
little more difficult (at times) to read the code. Everyone that reads
your code will appreciate you for it.
Because the student and grade arrays are parallel arrays you would want the minGrade() and maxGrade() methods to return a specific array index value to either the lowest or highest grade so that a referential relationship can be made toward the student that contains that specific grade determined. So, this would be far more useful:
public static int minGrade(int[] arr, int size) {
// Initialize min to have the highest possible value.
int min = Integer.MAX_VALUE;
int returnableIndex = -1;
// loop to find lowest grade in array
for (int i = 0; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
returnableIndex = i;
}
}
return returnableIndex;
}
public static int maxGrade(int[] arr, int size) {
int max = Integer.MIN_VALUE;
int returnableIndex = -1;
// loop to find highest grade in array
for (int i = 0; i < size; i++) {
if (arr[i] > max) {
max = arr[i];
returnableIndex = i;
}
}
return returnableIndex;
}
With everything in play your code might look like this:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
// Number Of Students...
String amountString = "";
while (amountString.isEmpty()) {
System.out.print("How many students do you have?: --> ");
amountString = scan.nextLine().trim();
// Is the supplied Number Of Students valid and within
// range (1 to 50 inclusive)?
if (!amountString.matches("\\d+") || Integer.valueOf(amountString) < 1
|| Integer.valueOf(amountString) > 50) {
// No...
System.err.println("Invalid entry (" + amountString + ") for Student "
+ "amount! Try again...");
amountString = ""; // Empty inputString so we loop again.
System.out.println();
}
}
// Valid amount provided.
int amount = Integer.valueOf(amountString);
// Declare and initialize parallel arrays
String[] student = new String[amount];
int grade[] = new int[amount];
// Student Names and Grade...
for (int i = 0; i < amount; i++) {
// Student Name...
String name = "";
while (name.isEmpty()) {
System.out.print("Enter student #" + (i + 1) + " name: --> ");
name = scan.nextLine().trim();
/* Is the name valid (contains upper or lower case letters from
A-Z and a single whitespaces separating first and last name?
Whitespace and last name is optional. */
if (!name.matches("(?i)([a-z]+)(\\s{1})?([a-z]+)?")) {
// No..
System.err.println("Invalid Student #" + (i + 1) + " name ("
+ name + ")! Try Again...");
System.out.println();
name = ""; // Empty name so we loop again.
}
}
// Valid Student name provided...
student[i] = name;
// Student Grade...
String gradeString = "";
while (gradeString.isEmpty()) {
System.out.print("Enter student #" + (i + 1) + " grade: --> ");
gradeString = scan.nextLine().trim();
// Is the supplied grade valid and within range (0 to 100 inclusive)?
if (!gradeString.matches("\\d+")
|| Integer.valueOf(gradeString) < 0
|| Integer.valueOf(gradeString) > 100) {
// No...
System.err.println("Invalid entry (" + gradeString + ") for "
+ "Student #" + (i + 1) + " grade! Try again...");
gradeString = "";
System.out.println();
}
}
// Valid Student grade provided...
grade[i] = Integer.valueOf(gradeString);
}
// Display everyone's grade
System.out.println();
for (int i = 0; i < amount; i++) {
System.out.println(student[i] + " received the final grade of " + grade[i]);
}
System.out.println();
//Display who is highest and lowest...
int index = maxGrade(grade, amount);
System.out.println("The highest grade in the class was by '" + student[index]
+ "' with a grade of: " + grade[index]);
index = minGrade(grade, amount);
System.out.println("The lowest grade in the class was by '" + student[index]
+ "' with a grade of: " + grade[index]);
}
public static int minGrade(int[] arr, int size) {
// Initialize min to have the highest possible value.
int min = Integer.MAX_VALUE;
int returnableIndex = -1;
// loop to find lowest grade in array
for (int i = 0; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
returnableIndex = i;
}
}
return returnableIndex;
}
public static int maxGrade(int[] arr, int size) {
int max = Integer.MIN_VALUE;
int returnableIndex = -1;
// loop to find highest grade in array
for (int i = 0; i < size; i++) {
if (arr[i] > max) {
max = arr[i];
returnableIndex = i;
}
}
return returnableIndex;
}
If the data are not sorted, it would be better to find both min and max grades in the same loop, after printing the students and their grades.
Then no loop is needed to print min and max grades:
for (int i = 0; i < amount; i++) {
System.out.println(student[i] + " received the final grade of " + grade[i]);
}
int min = grade[0];
int max = grade[0];
for (int i = 1; i < amount; i++) {
if (grade[i] < min) {
min = grade[i];
} else if (grade[i] > max) {
max = grade[i];
}
}
System.out.println("The highest grade in the class was " + max);
System.out.println("The lowest grade in the class was " + min);
If the index of min/max is sought, it would be possible to print the name of the students who get the min and max grades.
public static void main(String[] args) {
int[] grades = new int[]{50, 51, 52, 50, 60, 22, 53, 70, 60, 94, 56, 41};
int[] result = getMinMax(grades);
System.out.println("Min: " + result[0] + ", Max: " + result[1]);
}
public static int[] getMinMax(int[] values) {
int[] result = new int[]{Integer.MAX_VALUE, Integer.MIN_VALUE};
for (int i : values) {
result[0] = i < result[0] ? i : result[0];
result[1] = i > result[1] ? i : result[1];
}
return result;
}
You'll need to handle the case of int[] values being null or empty. You can decide that (Throw an exception, return null... or whatever)
I am practicing sorting of arrays, and I have successfully sorted a string array.
My little program allows users to enter first number of students, then the name of each one, and at last their grade of each one.
But I also want to sort the int studentGrade array so that the grades in the printout matches the student. Here I am really stuck. See further down for more explanation down in the method: public void sortingAlgorithm
package assignment8exam;
import java.util.Scanner;
import java.util.Arrays;
/**
*
* #author Anders
*/
public class Course {
Scanner sc = new Scanner(System.in);
public void MainMenu() {
System.out.println("Enter data about a student, start by entering how many");
int numbers = sc.nextInt();// amount of student
String studentNames[] = new String[numbers];
int studentGrade[] = new int[numbers];
for (int i = 0; i < numbers; i++) {
System.out.println("Enter name of student");
Scanner name = new Scanner(System.in);
String names = name.nextLine();
studentNames[i] = names;
}
for (int j = 0; j < numbers; j++) {
System.out.println("Enter grade of student");
Scanner gradeSc = new Scanner(System.in);
int grade = gradeSc.nextInt();
studentGrade[j] = grade;
}
sortingArray(studentNames);
System.out.println("------------------------------------\n");
sortAlgorithm(studentNames, studentGrade);
System.out.println("What do you want");
System.out.println("Exit application 1");
System.out.println("Print out all names of the students 2");
System.out.println("Print out all the grades of the students 3");
System.out.println("Print out pairs consisting of “namegrade 4");
System.out.println("Search for a student - 5");
Scanner choice = new Scanner(System.in);
int order = choice.nextInt();
switch (order) {
case 1:
System.exit(1);
case 2:
PrintOutNames(numbers, studentNames);
case 3:
PrintOutGrades(numbers, studentGrade);
case 4:
PrintOutAll(numbers, studentGrade, studentNames);
case 5:
search(numbers, studentGrade, studentNames);
}
}
public static void PrintOutNames(int numbers, String studentNames[]) {
for (int i = 0; i < numbers; i++) {
System.out.println(studentNames[i]);
}
}
public static void PrintOutGrades(int numbers, int studentGrade[]) {
for (int i = 0; i < numbers; i++) {
System.out.println(studentGrade[i]);
}
}
public static void PrintOutAll(int numbers, int studentGrade[], String studentNames[]) {
System.out.println("--------------------------------------------------------\n");
for (int i = 0; i < numbers; i++) {
System.out.println("Name----> " + studentNames[i] + " grade ---> " + studentGrade[i]);
}
}
public static void search(int numbers, int studentGrade[], String studentNames[]) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter name on student you want to search on ");
String search = sc.nextLine();
for (int i = 0; i < numbers; i++) {
if (search.equals(studentNames[i])) {
System.out.println("Yes we have a student named " + studentNames[i] + " with the Grade " + studentGrade[i] + " \n ");
}
}
}
public static void sortingArray(String studentNames[]) {
Arrays.sort(studentNames);
System.out.println("-------------\n" + Arrays.toString(studentNames));
}
public static void sortAlgorithm(String studentNames[], int studentGrade[]) {
boolean flag = true;
while (flag) {
flag = false;
for (int j = 0; j < studentNames.length - 1; j++) {
for (int i = j + 1; i < studentNames.length; i++) {
if (studentNames[i].compareTo(studentNames[j]) < 0) {
String temp = studentNames[j];
studentNames[j] = studentNames[i];
studentNames[i] = temp;
// Here i want to place another array that sorts the grade?? how do i do that?
}
}
System.out.println(Arrays.toString(studentNames));
System.out.println(Arrays.toString(studentGrade));
}
}
}
}
The problem with your approach is that there is no relation between a student name and grade. If you sort the names and sort the grades you will end up with students with letter A having the least grades.
If that's a java assignment the best way to do it would be to create a data structure (class) called Student that has name and grade.
class Student{
String name;
int grade;
}
Then you will not have two arrays one with names and other with grades but just one array of Students and you will be able to sort that array by grades,names etc.
If you want a quicker solution that would be to use a map like Map<String,Integer> that will contain the grade for each student.
If you want to use multiple array you can make the sortAlgorithm method to swap the same indexes in both arrays (not only in the names array) and this way you will end up with grades sorted by names. This is the worst approach IMO because you depend too much on the array indexes instead of having some relation between the objects.
In this particular case, the solution is relatively easy. In this place, where you exchange the two student names:
for (int i = j + 1; i < studentNames.length; i++) {
if (studentNames[i].compareTo(studentNames[j]) < 0) {
String temp = studentNames[j];
studentNames[j] = studentNames[i];
studentNames[i] = temp;
}
}
You also exchange the corresponding grades at the same time:
for (int i = j + 1; i < studentNames.length; i++) {
if (studentNames[i].compareTo(studentNames[j]) < 0) {
String temp = studentNames[j];
studentNames[j] = studentNames[i];
studentNames[i] = temp;
int tempGrade = studentGrades[j];
studentGrades[j] = studentGrades[i];
studentGrades[i] = tempGrade;
}
}
So, whenever you do a switch of two student names, you switch the corresponding grades at the same time. This will keep the two arrays synchronized.
But as everybody else has been recommending, the better way is to create a class that represents a student - both name and grade. Why? Because in a real world case, a student may have other data, such as different subjects and their matching grades, an attendance record, contact information, whatever the university needs.
And having to add that to the loop for each such data item will make it intractable. If you have all the information in one record, you can just exchange record references, and then the whole data is exchanged together.
The basis for this is a class like:
class Student implements Comparable<Student> {
private String name;
private int grade = 0;
public Student( String name ) {
this.name = name;
}
public void setGrade( int grade ) {
this.grade = grade;
}
// In addition, you'll have getName(), getGrade(),
// and possibly a good `toString()` for printing a
// student record.
#Override
public int compareTo( Student otherStudent ) {
return this.name.compareTo( otherStudent.name );
}
}
Now you can define an array such as:
Student[] students = new Students[numbers];
And you can sort it directly with Arrays.sort() because Student implements Comparable, or you can do your own sorting algorithm and use the compareTo method. Your loop would be:
for (int i = j + 1; i < students.length; i++) {
if (students[i].compareTo(students[j]) < 0) {
Student temp = students[j];
students[j] = students[i];
students[i] = temp;
}
}
As noted above, the "correct" solution is probably to create a Student object and have it contain the student's name and grade. However, if you really need to have two separate arrays, you could just perform the same swapping on on the grade array that you do on the name array:
if (studentNames[i].compareTo(studentNames[j]) < 0) {
String temp = studentNames[j];
studentNames[j] = studentNames[i];
studentNames[i] = temp;
int tempGrade = studentGrade[i];
studentGrade[j] = studentGrade[i];
studentGrade[i] = tempGrade;
}
What you want to do, is Sort the grade array according to the student array i think, so in you for loop, everytime you switch a student, you want to switch the grade
for (int j = 0; j < studentNames.length - 1; j++) {
for (int i = j + 1; i < studentNames.length; i++) {
if (studentNames[i].compareTo(studentNames[j]) < 0) {
String temp = studentNames[j];
studentNames[j] = studentNames[i];
studentNames[i] = temp;
// Here i want to place another array that sorts the grade?? how do i do that?
int tempGrade = studentGrades[j];
studentGrades[j] = studentGrades[i]
studentGrades[i] = temp
}
}
System.out.println(Arrays.toString(studentNames));
System.out.println(Arrays.toString(studentGrade));
}
this design isn't that good, maybe take the advice from #Veselin Davidov in account
Your problem is that when you sort one array (say your student name list), your second array cant keep up with the same way.... apples and oranges.
You have somes solutions. The one that comes in mind right now is to use a map linking each name to its grade. You could also, well, use POO and declare a Studen object, that actually would look like a nicer solution, i'll let you read on Veselin's answer for that.
Let's look at the quickfix though, since i think that's why you're looking for :
Personally one workaround to your kinda-broken code would be to change your swap function to this :
if (studentNames[i].compareTo(studentNames[j]) < 0) {
String tmp = studentNames[j];
studentNames[j] = studentNames[i];
studentNames[i] = tmp;
int tmpGrade = studentGrade[i];
studentGrade[j] = studentGrade[i];
studentGrade[i] = tmpGrade;
}
But, i strongly recommend using either classes or a map.
You should really have an abstraction representing a Student, e.g.
public class Student {
Integer grade;
String name;
// getters and setters omitted
}
Then, you'll face the problem of extending the Comparator interface multiple times with different types (Integer and String). At this point, read this :
Using Comparable for multiple dynamic fields of VO in java
I need to find another way to comunicate the more populated city of an array.
The code is like this but sometimes he give me the right city name, and sonetimes he give me the wrong city name, does somebody have any idea?
public class Esercizio32_101
{
public static void main(String[] args)
{
// Object for InputStream
ConsoleReader2 tastiera = new ConsoleReader2(System.in);
// declarations
String names[] = new String[5];
int population[] = new int[5];
String n = null;
int higher = 0;
int total = 0;
int c = 0;
// calcoli
for (int i = 0; i < names.length; i++)
{
System.out.print("Insert the name of city N° " + (i + 1) + " ===> ");
do
{
names[i] = tastiera.readLine();
if (names[i].equals(""))
{
System.out.print("You must insert the city name, try again ===> ");
}
}
while (names[i].equals(""));
}
for (int i = 0; i < names.length; i++)
{
System.out.print("Insert the population of city N° " + (i + 1) + " ===> ");
population[i] = tastiera.readInt();
total = population[i];
if (total > higher)
{
higher = total;
c++;
}
}
System.out.print("The most populated city is " + names[c]);
}
}
The most immediate problem is here:
if (total > higher)
{
higher = total;
c++;
}
By incrementing c you're just remembering how many cities had a larger population than any of the preceding ones. You want to remember the index of the more populous city:
if (total > higher)
{
higher = total;
c = i;
}
Additionally, I would strongly advise you to create a City type to encapsulate the "name and population". Ask for all the city details to populate a List<City> or a City[], and then you can find the most populous city. Any time you find yourself with multiple collections which will all have the same size, you should consider refactoring to one collection with a type that encapsulates one value for each of the original collections.
That approach will also encourage you to separate "data gathering" from "data processing" - currently you're detecting the largest population while you're asking the user for input. That means if you later wanted to handle the situation where the data was loaded from disk, you'd need to rewrite things. If you separate out the different concerns, it'll make your code easier to modify and test.
Finally, I'd suggest you think more carefully about variable names. In what way does total communicate the intent of "the population of the city I'm asking about at the moment"?
replace
c++;
by
c = i;
It will work in all cases.
Just take in consideration the value of the index that have the max value of the population. Incrementing c dosen't make sense as long as you need to keep track of the index for the max value of population[i].
Instead try this:
public class Esercizio32_101
{
public static void main(String[] args)
{
// Object for InputStream
ConsoleReader2 tastiera = new ConsoleReader2(System.in);
// declarations
String names[] = new String[5];
int population[] = new int[5];
String n = null;
int higher = 0;
int total = 0;
int c = 0;
// calcoli
for (int i = 0; i < names.length; i++)
{
System.out.print("Insert the name of city N° " + (i + 1) + " ===> ");
do
{
names[i] = tastiera.readLine();
if (names[i].equals(""))
{
System.out.print("You must insert the city name, try again ===> ");
}
}
while (names[i].equals(""));
}
for (int i = 0; i < names.length; i++)
{
System.out.print("Insert the population of city N° " + (i + 1) + " ===> ");
population[i] = tastiera.readInt();
total = population[i];
if (total > higher)
{
higher = total;
c=i;//here is the change c should keep track of the higher total of population, if c dosent change then the fist value of the array population[] (i=0) have the biggest value.
}
}
System.out.print("The most populated city is " + names[c]);
}
}
What I’m attempting to do is search “gradePsd” array find the highest grade and if there are two grades that are the same value print the name (s) of the students to console.
The problem I’m having is that this method is taking the first index value of the array and printing it because it IS the high value at the first pass and if the second value is larger than the first then it will also print and so on.
So my question is how can I get it to just print the student (s) with the high grade.
public static void hiMarkMethod(String[] NamePsd, int[] gradePsd)
{
String nameRtn = "";
int num = gradePsd[0];
System.out.println ("\n\nThe Student(s) with Hightest Mark(s) are:");
for (int i = 0; i < gradePsd.length; i++)
{
if (gradePsd[i] >= num)
{
num = gradePsd[i];
nameRtn = NamePsd[i];
}
System.out.print(nameRtn + ", ");
}
}
first find the highest number
then print the students with that number
public static void hiMarkMethod(String[] NamePsd, int[] gradePsd)
{
String nameRtn = "";
int num = gradePsd[0];
System.out.println ("\n\nThe Student(s) with Hightest Mark(s) are:");
//find the highest number
for (int i = 0; i < gradePsd.length; i++){
if (gradePsd[i] >= num){
num = gradePsd[i];
}
//print students with that number
for (int j = 0; j < NamePsd.length; j++){
if (gradePsd[j] == num)
{
nameRtn = NamePsd[j];
System.out.print(nameRtn + ", ");
}
}
one of possible 1000 solutions.
Initialize num with -1 and take the System.out out of the for loop. But you can only determine one student with your code. You need nameRtn to be a Collection if you want to store more than one name.
Something like this:
public static void hiMarkMethod(String[] NamePsd, int[] gradePsd) {
Collection<String> namesRtn = new ArrayList<String>();
int num = -1;
for (int i = 0; i < gradePsd.length; i++) {
if (gradePsd[i] > num) {
num = gradePsd[i];
namesRtn.clear(); // clear name list as we have a new highest grade
namesRtn.add(NamePsd[i]); // store name in list
} else if (gradePsd[i] == num) {
namesRtn.add(NamePsd[i]); // if a second student has the same grade store it to the list
}
}
System.out.println ("\n\nThe Student(s) with Hightest Mark(s) are: " + namesRtn);
}
Note: Just a practice problem, not for marks.
This is a practice problem given in a first year Java course:
Design and implement an application that reads an arbitrary number of integers, by the user, that are in the range 0 to 50 inclusive, and counts how many occurrences of each are entered. After all the input has been processed, print all of the values (with the number of occurrences) that were entered one or more times.
In addition, write a method that returns no value which would compute the average of the occurrences of all numbers entered by the user.
This is what I have (I have skipped the "average occurrence" part until I clean this up):
import java.util.Scanner;
public class Main
{
public static Scanner scan = new Scanner(System.in);
public static int[] userIntegers() // this method will build the array of integers, stopping when an out-of-range input is given
{
System.out.println("Enter the number of integers to be recorded: ");
int numInts = scan.nextInt();
int[] userArray = new int[numInts];
int i = 0;
while(i < numInts)
{
System.out.println("Enter an integer between 1-50 inclusive: ");
int userInteger = scan.nextInt();
if(isValidInteger(userInteger))
{
userArray[i] = userInteger;
i++;
}
else if(isValidInteger(userInteger) == false)
{
System.out.println("Try again.");
}
}
return userArray;
}
public static void occurrenceOutput(int[] input) // this method will print the occurrence data for a given array
{
int[] occurrenceArray = new int[51];
int j = 0;
while(j < 51) // iterates through all integers from 0 to 50, while the integer in the array is equal to integer j, the corresponding occurance array element increments.
{
for(int eachInteger : input)
{
occurrenceArray[j] = (eachInteger == j)? occurrenceArray[j]+=1: occurrenceArray[j];
}
j++;
}
int k = 0;
for(int eachOccurrence : occurrenceArray) // as long as there is more than one occurrence, the information will be printed.
{
if(eachOccurrence > 1)
{
System.out.println("The integer " + k + " occurrs " + eachOccurrence + " times.");
}
k++;
}
}
public static boolean isValidInteger(int userInput) // checks if a user input is between 0-50 inclusive
{
boolean validInt = (51 >= userInput && userInput >= 0)? true: false;
return validInt;
}
public static void main(String[] args)
{
occurrenceOutput(userIntegers());
}
}
Can someone point me in a more elegant direction?
EDIT: Thanks for the help! This is where I am at now:
import java.util.Scanner;
public class simpleHist
{
public static void main(String[] args)
{
getUserInputAndPrint();
getIntFreqAndPrint(intArray, numberOfInts);
}
private static int numberOfInts;
private static int[] intArray;
private static int[] intFreqArray = new int[51];
public static void getUserInputAndPrint()
{
// The user is prompted to choose the number of integers to enter:
Scanner input = new Scanner(System.in);
System.out.println("Enter the number of Integers: ");
numberOfInts = input.nextInt();
// The array is filled withchInteger = integer; integers ranging from 0-50:
intArray = new int[numberOfInts];
int integer = 0;
int i = 0;
while(i < intArray.length)
{
System.out.println("Enter integer value(s): ");
integer = input.nextInt();
if(integer > 50 || integer < 0)
{
System.out.println("Invalid input. Integer(s) must be between 0-50 (inclusive).");
}
else
{
intArray[i] = integer;
i++;
}
}
// Here the number of integers, as well as all the integers entered are printed:
System.out.println("Integers: " + numberOfInts);
int j = 0;
for(int eachInteger : intArray)
{
System.out.println("Index[" + j + "] : " + eachInteger);
j++;
}
}
public static void getIntFreqAndPrint(int[] intArray, int numberOfInts)
{
// Frequency of each integer is assigned to its corresponding index of intFreqArray:
for(int eachInt : intArray)
{
intFreqArray[eachInt]++;
}
// Average frequency is calculated:
int totalOccurrences = 0;
for(int eachFreq : intFreqArray)
{
totalOccurrences += eachFreq;
}
double averageFrequency = totalOccurrences / numberOfInts;
// Integers occurring more than once are printed:
for(int k = 0; k < intFreqArray.length; k++)
{
if(intFreqArray[k] > 1)
{
System.out.println("Integer " + k + " occurs " + intFreqArray[k] + " times.");
}
}
// Average occurrence of integers entered is printed:
System.out.println("The average occurrence for integers entered is " + averageFrequency);
}
}
You are actually looking for a histogram. You can implement it by using a Map<Integer,Integer>, or since the range of elements is limited to 0-50, you can use an array with 51 elements [0-50], and increase histogram[i] when you read i.
Bonus: understanding this idea, and you have understood the basics of count-sort
To calculate occurences, you can do something like this:
for(int eachInteger : input) {
occurrenceArray[eachInteger]++;
}
This will replace your while loop.