Cycle while with scanner hasNext() - java

I have a problem when I try to run my work.
I have to put in some numbers by console and It should arrange in ascending order them and save to an array.
I thought that method hasNext worked well with String.nextLine(), but it seems to still in loop.
thanks for help
import java.util.Scanner;
public class OrdinamentoMaggiore{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("Digita dei numeri e te li mettero' in ordine crescente: ");
String Numeri = sc.nextLine();
int dimArray = 0;
while (sc.hasNext(Numeri)){
dimArray++;
System.out.println("Dimensione array: " + dimArray);
}
int min = 0, max = 0, temp;
int[] mioArray = new int[dimArray];
for (int i = 0; i <= mioArray.length; i++){
mioArray[i] = Integer.parseInt(sc.next(Numeri));
}
for (int j = 0; j <= mioArray.length; j++){
for (int h = 1; h <= mioArray.length; h++){
if (mioArray[j] < mioArray[h]){
continue;
}
else {
temp = mioArray[j];
mioArray[j] = mioArray[h];
mioArray[h] = temp;
}
}
}
System.out.println("Min: " + mioArray[0]);
System.out.println("Max: " + mioArray[dimArray]);
sc.close();
}
}

The problem is that you are reading the first line of input into the variable Numeri. Then, you are calling hasNext on Numeri which isn't working the way you think it is. Scanner.hasNext is defined here as:
Returns true if the next token matches the pattern constructed from
the specified string.
So it is using the string in Numeri as the pattern it needs to match. Definitely not what you want.
I would recommend a list and doing something like this:
List<Integer> numberList = new ArrayList<>();
while (sc.hasNextInt()) {
numberList.add(sc.nextInt());
}
Collections.sort(numberList);
A list is nice because you don't have to explicitly tell it the size. That avoids your first loop. Now, the loop goes continues reading from System.in until it encounters something that isn't an integer and adds them to the list.
Finally, it uses Collections.sort to sort the list. How beautiful is that? Your whole program can be reproduced in just a few lines. Definitely try and learn the libraries and functions that are available to you. It can save you a lot of time and effort. Let me know if you have questions.

Related

Java: how to stop blank arrays position from showing null in the terminal?

I have the following code that gets an element from the terminal with the Scanner class and adds it to a shopping cart array. It works fine, except that when I try to print the cart it'll show the unfilled positions of the array as "null". I digged over some topics here and someone sugested to create the first array with blank spaces for each of the 5 position (like String[] test = new String[]{"","","","",""};, but that didn't work. What should I do to "fix" this?
import java.util.Arrays;
import java.util.Scanner;
public class ex03 {
public static void main(String[] args) {
Scanner frutas = new Scanner(System.in);
String[] nomesFrutas = new String[5];
System.out.println("Insira a sua lista de compras.");
for (int i = 0; i <= nomesFrutas.length; i++) {
nomesFrutas[i] = frutas.next();
System.out.println("As frutas no seu carrinho são: \r\n " + Arrays.toString(nomesFrutas));
}
}
}
it'll show the unfilled positions of the array as null
There's a couple ways to avoid uninitialized elements to show up.
A quick and lazy way would be to use the built-in functionality of the Arrays utility class. You can print a copy of the part that was populated and print it.
By the way, there's a bug in your code: condition i <= nomesFrutas.length would produce an ArrayIndexOutOfBounds during the very last iteration because nomesFrutas[i] would refer to an illegal index.
That's how you can make use of the utility method Arrays.copyOf():
for (int i = 0; i < nomesFrutas.length; i++) {
nomesFrutas[i] = frutas.next();
System.out.println("As frutas no seu carrinho são: \r\n "
+ Arrays.toString(Arrays.copyOf(nomesFrutas, i + 1)));
}
There are several drawbacks of this solution:
a new array needs to be allocated in memory at each iteration step just in order to print non-null elements (it's a good habit to be mindful while your action require creating new objects that are immediately thrown away, especially when it can be avoided);
as I've said it's a "lazy" way, because it doesn't require implementing things yourself, try not to overuse such ready-to-go options when you're learning.
Another approach would be to create your own method responsible for displaying a range of array elements:
for (int i = 0; i < nomesFrutas.length; i++) {
nomesFrutas[i] = frutas.next();
System.out.println("As frutas no seu carrinho são: \r\n ");
display(nomesFrutas, i + 1);
}
public static void display(String[] arr, int len) {
if (len < 1) return;
System.out.print('[');
for (int i = 0; i < len; i++) {
System.out.print(arr[i]);
if (i < len - 1) System.out.print(", ");
else System.out.print(']');
}
}
Fill free to play around with this solution and adjust it in whatever way you see fit.

Java: How to fill out two arrays, alternating between the two

I have a program that has two String arrays defined and initialized. I now want to accept inputs from the user to fill out the indexes of each array. I want the user to input index[i] for array 1 and then index[i] for array 2 and so on until both arrays are filled.
I attempted to use a nested loop to do this, but I was getting an out of bounds error.
Unfortunately, Google was not helpful as I kept finding the .fill() method, which I cannot currently use in my course.
The code below contains elements for the rest of the program which I haven't written. The below code is meant to complete the first part of the program and that is to get the list of words into the first two arrays and then output them to make sure they were filled correctly.
EDIT: Even though I got my answer, I tried updating the question for clarity. It looks like I was vastly overthinking the problem. It was my first time working with more than one array.
import java.util.Scanner;
public class LabProgram {
public static int findWordInWordList(String[] wordList, String wordToFind, int numInList) {
return -1; //Will replace words in a sentence, to be used coded and used later.
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] ogWords; //words to replace.
String[] newWords; //words to replace with.
String[] sentence; //the sentence that will be searched and have words replaced.
int pairSize; //size of the first two arrays.
pairSize = sc.nextInt();
ogWords = new String[pairSize];
newWords = new String[pairSize];
for (int i = 0; i < ogWords.length; i++) {
ogWords[i] = sc.next();
for (int j = 0; j < newWords.length; j++) {
newWords[j] = sc.next();
}
}
for (int i = 0; i < pairSize - 1; i++) { //Testing arrays
System.out.println(ogWords[i] + " " + newWords[i]);
}
}
}
The final for loop is just to test that the arrays were filled correctly, which isn't working right now :p.
Unless I've misunderstood your question, I think you're after:
for (int i = 0; i < pairSize; i++) {
ogWords[i] = sc.next();
newWords[i] = sc.next();
}

Accessing index values before and after symbol from input

I am trying to take the input and if there is an # symbol in the input then it finds the maximum of the integers before and after the # symbol. The maximum part I have no problem with but I do not know how to access and find the values before and after the # symbol.
import java.util.Scanner;
public class Max_Min {
public static void main(String[] args) {
//gets keyboard
Scanner keyboard = new Scanner(System.in);
//puts input into string
String inputString = keyboard.nextLine();
//splits string between characters
String[] splitInput = inputString.split("");
for (String s : splitInput) {
if(s.equals("#")){
//computes the maximum of the two integers before and after the #
}
}
//close keyboard
keyboard.close();
I did do a search to find something simliar (and im sure there is something) but could not find anything. If someone could help that would be great!
Try with this:
for (int i = 0; i < splitInput.length; i++){
if (splitInput[i].equals("#") && i != 0 && i != splitInput.length -1){
int max = Math.max(Integer.parseInt(splitInput[i - 1]), Integer.parseInt(splitInput[i + 1]));
}
//...
}
You could try:
String[] splitInput = inputString.split("#");
which would split your string at the #s.
Then you can do a iteration over your splitInput array and do a .length on each index.
You have written the simple for loop, with which you can only access the string, but not its index in the array. If you had the index, you could write:
int possibleMax = Integer.parseInt(splitInput[i - 1]) + Integer.parseInt(splitInput[i + 1]);
To get the index, there are two ways:
for (int i = 0; i < splitInput.length; i++) {
String s = splitInput[i];
...
}
Or:
int i = 0;
for (String s : splitInput) {
…
i++;
}
I don't like either version because both are more complicated than absolutely necessary, in terms of written code. If you would use Kotlin instead of Java, it would be:
splitInput.forEachIndexed { i, s ->
…
}
In Java this could be written:
forEachIndexed(
splitInput,
(i, s) -> …
);
The problem in Java is that the code inside the … cannot update the variables of the enclosing method. I'm not sure whether this will ever change. It would be possible but needs a lot of work by the language committee.
A simple way to do this would be
String input = "12#23";
String [] arr = input.split("#");
if (arr.length == 2) {
System.out.println("Max is "+Math.max(Integer.valueOf(arr[0]),Integer.valueOf(arr[1])));
}

Read and Sort a file to array Java

I'm attempting to write a program that would read a file "data.txt" which has an undefined amount of numbers in random order, separated by line. It would add these numbers into an array and print out the numbers in one line, each separated by a comma "x, x1". Then on the next line it would print out (in the same format) the list of numbers which has been sorted from smallest to largest size.
Data type is integer.
Currently, I have coded for 3 methods which would allow the array to be sorted (I think they have no error).
I've created another method to read the file and am using a two-step process - once to figure out the number of lines in the file (I ask that this two-step process remain). This method seems to have trouble returning the "lineCount" and apparently I need to make this variable an array (which I find bizarre). How can I fix this code?
You may notice that my method for printing is empty; I have not figured out a way to print the array so that each number is separated by a comma. How do I code for this?
My code so far:
import java.util.*;
import java.io.*;
public class SortAndSearch {
public static void main(String[] args) {
readFile2Array();
printArray();
selectionSort();
printArray();
}
public static void printArray(int[] a) {
}
public static void selectionSort(int[] a) {
int minI = 0;
for (int k = 0; k < a.length - 1; ++k) {
minI = findMinIdx(a, k); // findMinIdx at k-th
swapElement(a, k, minI);// swapElement at k-th
}
}
public static int findMinIdx(int[] a, int k) {
int minIdx = k;
for (int i = k + 1; i < a.length; ++i)
if (a[i] < a[minIdx])
minIdx = i;
return minIdx;
}
public static void swapElement(int[] a, int i, int j) {
int temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static int[] readFile2Array(String fileName) {
File dat = new File("data.txt");
int lineCount = 0;
int[] a = new int[lineCount];
int i;
try{ Scanner sc = new Scanner(dat);
while (sc.hasNextLine()){ //first read to count -> int lineCount;
lineCount++;
return lineCount; //I have trouble with this line
}
while (sc.hasNextLine()){ //second read to array -> hasNext(),
a[i] = sc.nextInt();
return a;
}
}
catch (FileNotFoundException e) {
System.out.println("File cannot be opened");
e.printStackTrace();
}
}
public static int binarySearch(int[] arr, int val){
int minIdx, maxIdx, index = -1;
while(){ int middleIdx = (minIdx + maxIdx)/2;
if( arr[???] ==val){
index = middleIdx;
break } // update minIdx, maxIdx //if smaller then cut right, if larger then cut left
}
return index; }
}
The last method in the program would attempt to locate the element number of a user inputted number by using this (pseudo)code:
1. Let ‭min = 0‬ and ‭max = n-1‬ (where n is the array’s length)‬‬‬‬
2. If ‭max < min‬, then stop: ‭target‬ is not present in ‭array‬. return ‭false‬.‬‬‬‬‬‬‬‬
3. Compute ‭guess‬ as the average of ‭max‬ and ‭min‬, rounded down (so that it is an integer).‬‬‬‬‬‬
4. If ‭array[guess]‬ equals ‭target‬, then stop. You found it! Return ‭guess‬.‬‬‬‬‬‬
5. If the guess was too low, that is, ‭array[guess] < target‬, then set ‭min = guess + 1‬.‬‬‬‬
6. Otherwise, the guess was too high. Set ‭max = guess - 1‬.‬‬
7. Go back to step 2.
How would I code for this?
I would really appreciate any help in any area of this program!
Managed to fix the first part of the code:
readFile2Array method:
public static int[] readFile2Array(String fileName) {
try {
int lineCount = 0;
Scanner sc = new Scanner(new File("data.txt"));
while (sc.hasNext()) { // first read to count -> int lineCount;
lineCount++; // second read to array -> hasNext(),
sc.nextLine();
}
sc.close();
sc = new Scanner(new File("data.txt"));
int[] x = new int[lineCount];
int n = 0;
while (sc.hasNext()) {
x[n] = Integer.parseInt(sc.nextLine());
n++;
}
sc.close();
return x;
} catch (FileNotFoundException e) {
System.out.println("File cannot be opened");
e.printStackTrace();
}
return null;
}
Print array separated by comma:
public static void printArray(int[] a) {
try {
int lineCount = 0;
Scanner sc = new Scanner(new File("data.txt"));
while (sc.hasNext()) {
lineCount++;
sc.nextLine();
}
sc.close();
for (int i = 0; i < a.length; ++i) {
System.out.print(a[i]);
if (i < lineCount-1) System.out.print(", ");
}
} catch (FileNotFoundException e) {
System.out.println("File cannot be opened");
}
System.out.println();
}
Last method is still a mystery to me though!
I agree with VGR that you haven't actually asked a question, but by reading your code I guess that you were describing what you wanted to achieve...
There are some flaws in your readFile2Array-method, which might solve the problem:
1)
int lineCount = 0;
int[] a = new int[lineCount]; //The size of a will always be 0, so you can't add anything to it, even though you are trying to do this later. Consider using a List instead, as the size of the list can increase dynamically.
2)
while (sc.hasNextLine()){ //first read to count -> int lineCount;
lineCount++;
return lineCount; //I have trouble with this line
}
//The problem is the return type: You method signature states that you will return int[], but here you are trying to return an int.
//It will also just increase lineCount once and try to return this.
3)
//Your scanning will be at the 2nd line because of 2) and not going through the entire file again. To do this you need to create a new instance of Scanner. And the int[] a has a size of 0 at this point.
while (sc.hasNextLine()){ //second read to array -> hasNext(),
a[i] = sc.nextInt();
return a;
}
So in order to solve this you should refactor your code to something like:
public static List<Integer> readFile2Array(String fileName) {
File dat = new File("data.txt");
List<Integer> a = new ArrayList<>();
try{ Scanner sc = new Scanner(dat);
while (sc.hasNextLine()){
a.add(sc.nextInt());
}
sc.close(); //Always remember to close, when done :)
System.out.println("Added " + a.size() + " lines to the list.");
return a;
} catch (FileNotFoundException e) {
System.out.println("File cannot be opened");
e.printStackTrace();
return new ArrayList<>();
}
}
What I changed:
removed the lineCount as this is implicit stored in the size of the list called a.
Changed the int[] a to a List as this always will allow adding elements by increasing its size when needed.
Removed i as was never used, only initialized.
Removed the first while-loop as we don't need to know the amount of lines that is going to be added.
Added a return-statement in the catch-closure. We need to return something (even an empty array or maybe the not-yet-finished array)
I hope this helps. :)
I'm glad you got that part working. :)
To print out the array, it will be best to use whatever data you have of the array. By calling a.length, you don't have to count the number of lines from the input again, which you are not guaranteed are still the same if the input has changed in the mean time.
So this piece of code should do the trick:
public static void printArray(int[] a) {
for (int i = 0; i < a.length; ++i) {
System.out.print(a[i]);
if (i < a.length-1) System.out.print(", ");
}
System.out.println();
}

Sorting Strings as inserted into array in Java

I'm trying to create a program that takes user input and sorts it alphabetically as it comes in using compareTo String operations (not array.sort) and prints the final sorted array at the end. I've got most of the body of this problem down but am lost once I get to the sort function. Does anyone have any ideas on how I might be able to finish out the SortInsert method?
import java.util.*;
public class SortAsInserted {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int array_size = GetArraySize();
String[] myArray = new String[array_size];
for (int i = 0; i < array_size; i++){
String nextString = GetNextString();
String[] sortedArray = SortInsert(nextString, myArray);
}
PrintArray(sortedArray);
}
input.close();
}
}
public static String[] SortInsert(String nextString, String[] myArray){
for(int i = 0; i < myArray.length;)
if (nextString.compareToIgnoreCase(myArray[i]) > 0) {
i++;
//if current text is less(alphabetically) than position in Array
}else if (nextString.compareToIgnoreCase(myArray[i]) < 0){
}
}
public static int GetArraySize(){
Scanner input = new Scanner(System.in);
System.out.print("How many items are you entering?: ");
int items_in_array = input.nextInt();
return items_in_array;
}
public static void PrintArray(String[] x) {
for (int i = 0; i < x.length; i++){
System.out.print(x[i]);
}
}
public static String GetNextString(){
Scanner input = new Scanner(System.in);
System.out.println("Enter the next string: ");
String next_string = input.nextLine();
return next_string;
}
}
There are a number of problems with this code. First I'll answer your immediate question, then enumerate some of the other problems.
The SortInsert method takes a String[] that will have been initialized with null values, so you will need to take that into account. The for loop would look something like this. (I'm using comments instead of writing the actual code since I'm not doing the project)
for (int i=0; i<myArray.length; ++i) {
if (myArray[i] == null) {
// we found a blank spot. use it to hold nextString.
break;
} else if (nexString.compareToIgnoreCase(myArray[i]) < 0) {
// nextString should be in spot i, so make room for it
// by shuffling along whatever is in the array at "i" and later
// by one place, then put nextString into position "i"
break;
}
// otherwise we'll just move to the next position to check
}
Now for the other issues.
You have a Scanner object in main that is never used. There's no point in having it and closing it at the end if your other methods make their own.
myArray will always be the sorted array so there's no point in making a local variable called sortedArray and return it from SortInsert. Note that your attempt to print sortedArray would fail anyway because that local variable is only in scope within the for loop.
When printing it should be myArray being passed to PrintArray.
If you're going to sort as you go, the TreeMap data structure is what you should be using, not an array. However, if you want to sort as you go with an array, you need to add some lines into your else if clause in SortInsert (should be sortInsert, BTW). (Another question: why is it else if rather than just else?)
The lines should create a new array of size one greater than the existing array, copy the first i-1 elements of the old array to the new array, put the new element in position i, then copy the remaining elements of the old array into positions one greater in the new array.
Once you find the position you wish to insert at, you have to shift all of the following elements down by one. Something like the following:
String temp = array[position];
for (int j = position+1; j < array_size-1; j++) {
String temp2 = array[j];
array[j] = temp;
temp = temp2;
}
array[array_size-1] = temp;

Categories