Storing Inputs in Two Related Arrays - java

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 regions.
My idea is each time the user enters the region, the system will store it in an arrya and each time he enters a region, the system will ask him to enter the neighbours of that region before he enters the second region and so on, and store these inputs in a second array under a pointer of the related entry in the first array.
what I did is just the beginning as follow:
import java.util.Arrays;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
String [] regionArray = new String[5];
for (int i = 0; i < regionArray.length; i++) {
System.out.print("Please enter the region: ");
regionArray[i] = kb.next();
//kb.nextLine(); // to get and discard the nextline token
}
System.out.print("You have entered: ");
System.out.println(Arrays.toString(regionArray));
}
}
For example, assume we have 4 regions: a, b, c, d, and a has two neighbours: b and d. In this case when the user enters the first region which is (a), he will be asked to enter its neighbours which are b and d, then he will be able to enter the second region which is b and so on.
the problem now, How can I genereated the second array and make it linked to the first array?
Please help me
Thank you for your help. I really appreciate it.
Now I have used the Hashmap and everything is working well but I faced another problem in the retrieving specific region or neighbour. Besides that, I need to retrieve each one of them separatley in order to be able to apply four-colour theorem to each one of them, So how can I do that?
My Code was as following:
import java.util.*;
import java.util.HashMap;
public class Test5{
public static void main(String[]args){
HashMap<String, String> neighbour = new HashMap<String, String>();
Scanner kb = new Scanner(System.in);
for(;{
System.out.println ("Enter the neighbours first then the region... and when finished press q");
String n = kb.nextLine();
if (n.equalsIgnoreCase("Q"))
break;
System.out.print("region: ");
String region = kb.nextLine();
neighbour.put(region, n);
}
System.out.println(neighbour);
}
}

I suggest you use collections such as Map<String, Set<String>> where the key is the region and the Set contains the neighboring regions. I would also maintain a Set of the regions whose neighbours haven't been entered. Note: is 'a' neighbours 'b' it should also be the other way around.

I used the arrays, but unfortunately there is only one missed thing which is the size of neighbours array will be fixed for each region and this is will not be appropriate even in our real life.
For instance, if region A has two neighbours, that is not necessary that other regions have the same number of neighbours. So in this case what should I do?
Besides that, I have error in compiling my code, after entering the neighbours for the first region.
And this is my code:
import java.io.*;
import java.util.Scanner;
public class Test4 {
public static void main(String[] args) {
System.out.println("Please enter the number of neighbours");
Scanner kb = new Scanner(System.in);
BufferedReader reader = new BufferedReader(
new InputStreamReader(System.in));
try {
int size = Integer.parseInt(reader.readLine());
//SIZE is size of the neighbours array
String[][] regions = new String[5][size];
for (int i = 0; i < 5; i++) {
System.out.println("Please enter the region #"
+ (i + 1) + ": ");
String input = reader.readLine();
regions[i][0] = input; //get input for region;
for (int j = 1; j <= size; j++) {
System.out.println("Please enter the neighbour #"
+ (j) + ": ");
String n = reader.readLine();
regions[i][j] = n; //get input for neighbours
}
}
} catch (IOException ioe) {
System.out.println("An error have occured");
}
}
}

For instance, if region A has two neighbours, that is not necessary that other regions have the same number of neighbours. So in this case what should I do?
I'd recommend one of the proposed Collection solutions, but the goal may be to understand multi-dimensional arrays. You can have a different size for each neighbor array, but you'll have to determine the size for each row inside the outer loop, as suggested below.
import java.util.Arrays;
import java.util.Scanner;
public class Test5 {
private static final int REGION_COUNT = 2;
public static void main(String[] args) {
System.out.println("Please enter the number of neighbours; "
+ "enter 'q' to quit.");
Scanner kb = new Scanner(System.in);
String[][] regions = new String[REGION_COUNT][];
for (int r = 0; r < regions.length; r++) {
System.out.print("How many heighbors for region #"
+ (r + 1) + ": ");
if (kb.hasNextInt()) {
int size = kb.nextInt();
regions[r] = new String[size];
kb.nextLine();
for (int n = 0; n < size; n++) {
System.out.print("Please enter the neighbour #"
+ (n) + ": ");
regions[r][n] = kb.nextLine();
}
} else System.exit(0);
}
for (String[] neighbors : regions) {
System.out.println(Arrays.toString(neighbors));
}
}
}

You can create a class or structure with a region and an array of its neighbouring regions.So that you can access both the region easily.
Cheers,
Dwarak

This would be much easier using a combination of a Map and a Collection such as a Set:
Map<String, Set<String>> map = new HashMap<String, Set<String>>();
map.put("some region", new HashSet<String>());
map.get("some region").add("some neighbor");
map.get("some region").add("some other neighbor)";
System.out.println("some region's neighbors:");
for(String neighbor : map.get("some region")) {
System.out.println(neighbor);
}

Related

How to run while loop till user enter input?

I am trying to run while loop for each input user enter but don't know how to stop if user is not entering input.
I need help in stopping while loop if user doesn't enter input.
Code:
import java.util.*;
class petrol{
public static void main(String[] args){
int vehicle_counter=0,petrol_counter=0;
System.out.println("Enter quantity of petrol to be filled in vehicles seperated by space:");
Scanner s1 = new Scanner(System.in);
ArrayList<Integer> array = new ArrayList<Integer>();
while(true){
if(petrol_counter<=200 && array.size()<50){
int input = s1.nextInt();
petrol_counter=petrol_counter+input;
vehicle_counter++;
array.add(input);
}
else{
System.out.println("Quantity Excedded then 200 Litres or no of Vehicles excedded then 50.");
break;
}
}
System.out.println("Hii");
}
}
e.g: If I enter 2 3 4 2 and press enter loop should stop.
Problem with possible solution :
If I use while(s1.nextInt().equals(true)) I get an error.
How do I use break?
So, you can try something like this. Instead of Scanner, use BufferedReader to parse the input since all you need is a single line input. Also, BufferedReader is faster compared to Scanner.
Here is the code:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Petrol {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int vehicle_counter=0,petrol_counter=0;
System.out.println("Enter quantity of petrol to be filled in vehicles seperated by space:");
String input = br.readLine();
String[] values = input.split(" ");
if(values.length>50){
System.out.println("Vehicles exceeded 50");
}else{
for(int i=0;i<values.length;i++){
int ip = Integer.parseInt(values[i]);
petrol_counter+=ip;
vehicle_counter++;
if(petrol_counter>200){
System.out.println("Petrol Quantity exceeded 200L");
}
}
}
System.out.println(petrol_counter+" Litres "+ " Vehicles "+vehicle_counter);
}
}
If you want to keep the Scanner you could also make the input as char and having a if statement that will exit the loop when you press a certain character.
import java.util.*;
public class petrol {
public static void main(String[] args) {
int vehicle_counter = 0, petrol_counter = 0;
System.out.println("Enter quantity of petrol to be filled in vehicles seperated by space:");
Scanner s1 = new Scanner(System.in);
ArrayList<Integer> array = new ArrayList<Integer>();
while (true) {
if (petrol_counter <= 200 && array.size() < 50) {
char input = s1.next().charAt(0); // use char instead
if (input == 'q' || input == 'Q') { //if user enters q or Q
System.out.println("Quantity Excedded then 200 Litres or no of Vehicles excedded then 50.");
break;
}
petrol_counter = petrol_counter + input;
vehicle_counter++;
array.add((int) input); //Cast to int
}
}
System.out.println("Hii");
}
}

Set Array size and parse out String user input into Array

I need to set the array's size to be equal to numberResponses so that whatever number the user inputs, the array will be that size no matter how many movies they list. I know I could just declare the array with String[] favMoviesArray = new String(numberResponses); but then I'm not sure how to split the user's response into the different indexes of the array.
import java.util.Scanner;
import java.util.Arrays;
public class Assignment3 {
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
System.out.println("Your favorite movies:");
System.out.println("How many favorite movies do you have?");
String numberResponsesStr = userInput.nextLine();
int numberResponses;
try{
numberResponses = Integer.parseInt(numberResponsesStr);
}
catch(Exception e){
System.out.println("Invalid input. Please enter a number.");
return;
}
if(numberResponses < 1){
System.out.println("Invalid input. Please enter a positive number.");
return;
}
System.out.printf("List your %d favorite movies. Separate them with commas (Movie1, Movie2, Movie3, etc.).", numberResponses);
String favMovies = userInput.nextLine();
System.out.println();
String[] favMoviesArray = favMovies.split("\\s*,\\s*");
Arrays.sort(favMoviesArray);
System.out.printf("Your %d favorite movies are: %n", numberResponses);
System.out.println(Arrays.toString(favMoviesArray));
userInput.close();
}
}```
What you were thinking would work. You can declare the initial array to be the length specified by the user. Then you need to transfer into it from the split array, no more elements than it can hold, and no more than came out of the split. Math.min does that nicely, and I made a loop to do the copying.
If the user specifies more, only the ones that fit are used; I chose the first ones entered, but if you prefer do the first alphabetically, that's easier and makes for easier sorting. If less, the array is padded with ZZZ entries (which sort to the end).
Here is the result:
import java.util.Scanner;
import java.util.Arrays;
public class Assignment3 {
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
System.out.println("Your favorite movies:");
System.out.println("How many favorite movies do you have?");
String numberResponsesStr = userInput.nextLine();
int numberResponses;
try {
numberResponses = Integer.parseInt(numberResponsesStr);
} catch (Exception e) {
System.out.println("Invalid input. Please enter a number.");
return;
}
if (numberResponses < 1) {
System.out.println("Invalid input. Please enter a positive number.");
return;
}
String[] theUltimateArray = new String[numberResponses]; //just like you thought
for (int i = 0; i < numberResponses; i++) {
theUltimateArray[i] = "ZZZ"; //start ZZZ, not null, to avoid ugliness and bad sorts, and so these are at the end with this sentinel value
}
System.out.printf("List your %d favorite movies. Separate them with commas (Movie1, Movie2, Movie3, etc.).", numberResponses);
String favMovies = userInput.nextLine();
System.out.println();
String[] favMoviesArray = favMovies.split("\\s*,\\s*");
//Arrays.sort(favMoviesArray); don't sort yet, want the first ones entered, not first alphabetically
System.out.printf("Your %d favorite movies are: %n", numberResponses);
//System.out.println(Arrays.toString(favMoviesArray));
int n = Math.min(numberResponses, favMoviesArray.length); //number we can copy
for (int i = 0; i < n; i++) { //copy
theUltimateArray[i] = favMoviesArray[i];
}
Arrays.sort(theUltimateArray);
System.out.println(Arrays.toString(theUltimateArray)); //never larger than they said. Filled at end
userInput.close();
}
}

Java: I made a program that accepts input for an integer array & displays values in a table. Trying to recreate this using a string array. Pls. help,

Java is my first programming language, and I'm still unfamiliar with how arrays work. However, I was able to make this program, which accepts user-input for an integer array; it then outputs indexes and values, to show how arrays store numbers. I would like to recreate this program using a string array, to make a table containing a list of friends.
The .length property also confuses me...
Could someone explain the .length property and help me make the string array program work?
Thank you very much.
Here is the working code for the integer array table program
import java.util.*;
public class AttemptArrayTable
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Let me show you how arrays are stored ");
System.out.println("How many numbers do you want your array to
store? ");
int arrayInput [] = new int[scan.nextInt()];
System.out.println("Enter numbers ");
for (int count = 0; count<arrayInput.length; count++)
arrayInput[count] = scan.nextInt();
System.out.println("");
System.out.println("Index\t\tValue");
for (int count2=0; count2<arrayInput.length; count2++)
System.out.println(" [" + count2 + "]"+"\t\t " + arrayInput[count2]);
}
}
Here is the code for the string array program I'm working on
import java.util.*;
public class ArrayTableofFriends
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("How many female friends do you have? ");
String arrayOfFriendsFem [] = new String [scan.nextInt()];
System.out.println("List the name of your female friends");
for(int countF = 0; countF<arrayOfFriendsFem.length; countF++)
arrayOfFriendsFem[countF]= scan.nextLine();
System.out.println("How many male friends do you have? ");
String arrayOfFriendsMale [] = new String [scan.nextInt()];
System.out.println("List the name of your male friends");
for(int countM = 0; countM<=arrayOfFriendsFem.length; countM++)
arrayOfFriendsMale[countM]= scan.nextLine();
System.out.println("How many alien friends do you have? ");
String arrayOfFriendsAliens [] = new String [scan.nextInt()];
System.out.println("List the name of your alien friends");
for(int countA = 0; countA<=arrayOfFriendsFem.length; countA++)
arrayOfFriendsAliens[countA]= scan.nextLine();
{
System.out.println("Female\t\t\t" + "Male\t\t\t" + "Aliens");
for(int countF2 = 0; countF2<arrayOfFriendsFem.length; countF2++)
System.out.println(arrayOfFriendsFem[countF2]);
for(int countM2 = 0; countM2<=arrayOfFriendsMale.length; countM2++)
System.out.println("\t\t\t" + arrayOfFriendsMale[countM2]);
for(int countA2 = 0; countA2<=arrayOfFriendsAliens.length; countA2++)
System.out.println("\t\t\t\t\t\t" +arrayOfFriendsAliens[countA2]);
}
}
.length property stores number of elements in the array. But elements are starting from 0. So, when .length = 1, then there is only one element in the array, with index 0.
It seems in your String arrays program in the for loop the <= should be changed to <
Like this:
for (int countA = 0; countA < arrayOfFriendsFem.length; countA++)

Search & Display Info from Parallel Array

just another newbie here needing help with a coding dilemma. The program I'm trying to create is a small database that has to use three parallel arrays (userNumber, player, and highScore). The intention is that the user should enter the a user number at the prompt and the program will display the person's information. If the number entered doesn't exist then the program should show them the number they entered and make them re-enter a user number until a correct one is entered.
The problems I'm running into now is that the program doesn't accept any user number except the first user number in the array, whether or not it's a valid number in the array list. Also, the error message only displays the first "incorrect" number regardless of how many times a "wrong" number is entered.
In short, I guess the right questions would be:
1.) Exactly what should I change in order for the program to return the info for just the array entries that correspond to the entered userNumber?
2.) What do I change to make each error message display the "incorrect" number that was just entered?
Here's the code I have:
import java.util.Scanner;
public class HighScoreSearch
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int[] userNumber = new int[5];
String[] player = new String[5];
Double[] highScore = new Double[5];
userNumber[0]= 1;
userNumber[1]= 2;
userNumber[2]= 3;
userNumber[3]= 4;
userNumber[4]= 5;
player[0]= "Morpheus";
player[1]= "Neo";
player[2]= "Cereal Killer";
player[3]= "Crash Override";
player[4]= "Acid Burn";
highScore[0]= 853797.67;
highScore[1]= 999999.99;
highScore[2]= 15097.34;
highScore[3]= 864513.16;
highScore[4]= 543188.68;
System.out.print("Enter User# ");
int scan= input.nextInt();
int i=0;
while (scan!=userNumber[i])
{
System.out.printf("Error #%s Is Unknown User", scan);
System.out.print("Enter User# ");
scan=input.nextInt();
}
System.out.printf("%s, user# %s, has a high score of: %s", player[i], userNumber[i], highScore[i]);
}
}
You are not using the entered value - consider
while (scan < userNumber[0] || scan > userNumber[4])
{
System.out.printf("Error #%s Is Unknown User", scan);
System.out.print("Enter User# ");
scan=input.nextInt();
}
// now use the value
System.out.printf("%s, user# %s, has a high score of: %s",
player[scan-1], userNumber[scan-1], highScore[scan-1]);
Of course, you should really loop through the userNumber array to check if the number is there. In reality such a solution would require you to create single obejcts holding this information and then having a List or array of these objects
You should consider using a HashMap for your users instead of an array. Otherwise, you would have to loop through the entire array each time to find if the user exists.
Map<Integer, Integer> userMap = new HashMap<>();
// map user numbers to associative array indexes.
userMap.put(1, 0);
userMap.put(2, 1);
userMap.put(3, 2);
userMap.put(4, 3);
userMap.put(5, 4);
player[0]= "Morpheus";
player[1]= "Neo";
player[2]= "Cereal Killer";
player[3]= "Crash Override";
player[4]= "Acid Burn";
highScore[0]= 853797.67;
highScore[1]= 999999.99;
highScore[2]= 15097.34;
highScore[3]= 864513.16;
highScore[4]= 543188.68;
System.out.print("Enter User# ");
int scan= input.nextInt();
// loop until the user actually exists
while (!userMap.containsKey(scan))
{
System.out.printf("Error #%s Is Unknown User", scan);
System.out.println();
System.out.println("Enter User# ");
scan=input.nextInt();
}
// get the index for the user
int lookup = userMap.get(scan);
System.out.printf("%s, user# %s, has a high score of: %s", player[lookup], scan, highScore[lookup]);
Note
The other benefit with using this approach is that your user numbers don't have to be in order.
For example, you can have the following mapping and the code would still work:
userMap.put(1, 0);
userMap.put(2, 1);
userMap.put(9, 2); // user # 9 can map to index 2.
userMap.put(4, 3);
userMap.put(5, 4);
Per #ScaryWombat it would be ideal to create a Player class so you don't have to use associative arrays and make your program more OO.
Example:
class Player
{
private int id = 0;
private String name;
private Double score = 0.0;
public Player (int id, String name, double score)
{
this.id = id;
this.name = name;
this.score = score;
}
#Override
public String toString()
{
return String.format("%s, user# %s, has a high score of: %s", name, id, score);
}
}
Then, you can create a HashMap of Integer to Player
Map<Integer, Player> userMap = new HashMap<>();
userMap.put(1, new Player(1, "Morpheus", 853797.67));
userMap.put(2, new Player(2, "Neo", 999999.99));
userMap.put(3, new Player(3, "Cereal Killer", 15097.34));
userMap.put(4, new Player(4, "Crash Override", 864513.16));
userMap.put(5, new Player(5, "Acid Burn", 543188.68));
Now, you can look up the Player like this:
// get the player object for the user id
Player p = userMap.get(scan);
// print out the player like this since it has a toString()
System.out.println(p);
I'm proving another answer that uses arrays, since your requirement is to use parallel arrays. Please see all the comments in the code. I've added error checking so the program doesn't exit nor get into an invalid state.
The key here is that you have to loop through the entire array each time the user enters a potential user number.
import javax.swing.JOptionPane;
public class HighScoreSearch
{
// You need an indicator for an invalid user in the case where
// you don't use all array positions
private static final int INVALID_USER_NUM = -1;
public static void main(String[] args)
{
// consider renaming this int to something like userNumber (scan is not very meaningful)
int scan = 0;
int[] userNumber = new int[10];
String[] player = new String[10];
Double[] highScore = new Double[10];
userNumber[0]= 10;
userNumber[1]= 777;
userNumber[2]= 5;
userNumber[3]= 1234;
userNumber[4]= 357;
// set the rest to an invalid user #; otherwise these will have a value 0 by default
userNumber[5]= INVALID_USER_NUM;
userNumber[6]= INVALID_USER_NUM;
userNumber[7]= INVALID_USER_NUM;
userNumber[8]= INVALID_USER_NUM;
userNumber[9]= INVALID_USER_NUM;
player[0]= "Morpheus";
player[1]= "Neo";
player[2]= "Cereal Killer";
player[3]= "Crash Override";
player[4]= "Acid Burn";
highScore[0]= 853797.67;
highScore[1]= 999999.99;
highScore[2]= 15097.34;
highScore[3]= 864513.16;
highScore[4]= 543188.68;
// this represents the array index of the user across the arrays
int indexOfUser = 0;
// flag to indicate if we found a valid user
boolean userFound = false;
do
{
String replyBox = JOptionPane.showInputDialog("Enter User#");
// consider trimming this replyBox value
// If they enter "10 " (w/o quotes would you still want that to be valid)
replyBox = replyBox.trim();
scan = INVALID_USER_NUM; // default to an invalid user #
try
{
scan = Integer.parseInt(replyBox);
}
catch (java.lang.NumberFormatException nfe)
{
// they didn't enter a valid integer, but you don't want to exit the program
}
// don't bother searching if it's invalid
if (scan != INVALID_USER_NUM)
{
// loop through each user to see if you find the entered #
for (int i = 0; i < userNumber.length && !userFound; i++)
{
// we found this user
if (scan == userNumber[i])
{
indexOfUser = i;
userFound = true;
}
}
}
if (!userFound)
{
// you should use replyBox instead of scan here
//String messagefalse = String.format("Error %s is an Unknown User", scan);
String messagefalse = String.format("Error: '%s' is an Unknown User", replyBox);
JOptionPane.showMessageDialog(null, messagefalse);
}
} while (!userFound); // loop until we find a user
// we've found a user - use the indexOfUser to index the arrays
String messagetrue = String.format("%s, user# %s, has a high score of: %s", player[indexOfUser], userNumber[indexOfUser], highScore[indexOfUser]);
JOptionPane.showMessageDialog(null, messagetrue);
}
}

Input and storing Strings in two-dimensional arrays

My teacher explained two dimensional arrays in literally two paragraphs. He didn't give me any information on how to create them besides that and now I have to do an assignment.
I've read up a lot about it and I somewhat understand how a 2D array is like an array of arrays, but I'm still completely and utterly confused about how to apply it.
The assignment itself is very simple. It asks me to create a program that will ask a user for ten Criminal Records, (name, crime, year). This program will store the records in a two-dimensional array and then sort them using the selection sort.
I know this is probably wrong, but here is what I have so far based on what I've read:
public static void main(String[] args)throws IOException {
//create array
String[][] Criminals = new String[10][3]; // create 3 columns, 10 rows
int i, j;
int smallest; //smallest is the current smallest element
int temp; //make an element swap
String line;
//loop to request to fill array
for (int row = 1; row < Criminals.length; row++){
for (int col = 1; col < Criminals[row].length; col++){
System.out.print("Enter a criminal name: ");
Criminals[row][col] = br.readLine();
}
}
}
So far, I'm just trying to get the input and store it.
(Please try to be patient and thorough with me! Coding isn't my strongest point, but I'm trying to learn.) Any help would be amazing! Thanks in advance. :)
It looks fine for the most part. You should index arrays starting from 0, not 1. Your current code works but I'm guessing you don't want the same prompt for all entries. Thus it may be a good idea to use a single loop instead:
for (int row = 0; row < Criminals.length; row++) {
System.out.print("Enter a criminal name: ");
Criminals[row][0] = br.readLine();
System.out.print("Enter a crime: ");
Criminals[row][1] = br.readLine();
System.out.print("Enter a year: ");
Criminals[row][2] = br.readLine();
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//create array
String[][] criminals = new String[10][3]; // create 3 columns, 10 rows
int i, j;
int smallest; //smallest is the current smallest element
int temp; //make an element swap
String line;
//loop to request to fill array
for (int row = 0; row < criminals.length; row++){
System.out.print("Enter a criminal name: ");
while(in.hasNext()){
criminals[row][0] = in.nextLine();
System.out.print("Enter a crime: ");
criminals[row][1] = in.nextLine();
System.out.print("Enter a year: ");
criminals[row][2] = in.nextLine();
}
}
}
}
This will print the commands you need from user and will store it in criminals. You may sort in the end. Since you didn't gave any information how you want it sorted, I will leave it for you to do it.
PS: I changed the 2d array name from Criminals to criminals, it's a java's good practice to not use capital words for attributes and variables (use it only for class names)

Categories