This question already has answers here:
What is the reason for ArrayIndexOutOfBoundsException in my code?
(2 answers)
Closed 7 years ago.
Scenario:
I need to read an array of integers from the standard inputstream, reorder it in such a way that a prime number is always followed by two even numbers ensuring that the prime and even numbers are picked up from the array in the order in which they are present to build the prime-2even set. Any remaining numbers that can't be part of the set can be
placed at the end of the array in the order in which they appear. The input(in multiple lines) and expected output(in multiple lines) as below:
Input:
8 5 9 7 8 5 4 6 8
Expected output:
5 8 4 7 6 8 9 5
Attempt:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int totalElements = Integer.parseInt(scanner.nextLine());
Integer[] integers = new Integer[totalElements];
Integer[] primeTwoEvens = new Integer[totalElements];
Integer[] leftOvers = new Integer[totalElements];
for (int i = 0; i < integers.length; i++) {
integers[i] = scanner.nextInt();
}
// LOGIC
int notNullCounter = 0; // Variable to track how many elements of integers array has been set to null.
while (notNullCounter != integers.length) { // Repeat this process until all the elements of the integers array are null.
for (int i = 0; i < integers.length; i++) { // Iterate the integers array and check for primeTwoEvens and populate the primeTwoEvens array.
if (integers[i] != null) { // Is the element of integers array to be processed null? If no, proceed.
if (isPrime(integers[i])) { // Is the element of integers array prime? If yes, proceed.
System.out.println(integers[i] + " is prime..."); // Print statement for debugging purpose.
primeTwoEvens[i] = integers[i]; // Since the element of integers array is prime, add it to the primeTwoEvens array.
integers[i] = null; // Set this index of integers array to null.
notNullCounter++; // As one element of integers array has been set to null, increment the null counter.
int evenCounter = 0; // Variable to track even number occurrences.
while (evenCounter != 2) { // Repeat this process until 2 even numbers are not found.
for (int j = ++i; j <= integers.length; j++) { // Iterate the remaining elements of integers array and check for next two even numbers.
if (isEven(integers[j])) { // Is the element of integers array even? If yes, proceed.
System.out.println(integers[j] + " is even..."); // Print statement for debugging purpose.
evenCounter++; // Since the element of integers array is even, increment the even counter.
primeTwoEvens[++i] = integers[j]; // Since the element of integers array is even, add it to the primeTwoEvens array as well.
integers[j] = null; // Set this index of integers array to null.
notNullCounter++; // As one element of integers array has been set to null, increment the null counter.
}
}
}
} /*else { // Element is not prime.
}*/
}
}
//break;
}// End of while
/*System.out.println("############ PRINTING THE FINAL SORTED ARRAY ############");
for (Integer integer : integers) {
System.out.println(integer);
}*/
}
throws me an java.lang.ArrayIndexOutOfBoundsException
Output:
5 is prime...
8 is even...
4 is even...
6 is even...
8 is even...
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 8
at Ideone.main(Ideone.java:125)
Line 125:
if (isEven(integers[j]))
Note: I am restricted to using Java standard API and JDK 7.
How do I solve the problem and the final task?
I think the previous line (before Line 125) should be
for (int j = ++i; j < integers.length; j++)
Not <=
You could try this:
public static void main(String[] args) {
// Read your file (I just copy your example to an array)
Integer[] integers = new Integer[] { 8, 5, 9, 7, 8, 5, 4, 6, 8 };
List<Integer> prime = new ArrayList<Integer>(), even = new ArrayList<Integer>();
List<Integer> other = new ArrayList<Integer>(), ordered = new ArrayList<Integer>();
// Start adding until 1st prime appear
boolean firstPrime = false;
for (Integer number : integers) {
if (isPrime(number)) {
prime.add(number);
firstPrime = true;
} else if (firstPrime && isEven(number)) {
even.add(number);
}
// To have control of the order of appearance
if (firstPrime) other.add(number);
// If I have at least 1 prime and 2 even, then add them
// to my ordered list and remove them from all my other lists
if(prime.size() >= 1 && even.size() >= 2){
ordered.add(prime.get(0));
ordered.add(even.get(0));
ordered.add(even.get(1));
other.remove(prime.get(0));
other.remove(even.get(0));
other.remove(even.get(1));
even.remove(1);
even.remove(0);
prime.remove(0);
}
}
ordered.addAll(other);
System.out.println(ordered);
}
If you run this example, you will have
[5, 8, 4, 7, 6, 8, 9, 5]
Related
Basically i want to generate random numbers between 1-10, which are put into my set. The thing is that my loop size is from 0 to 9 and it generates random numbers but, once it's 5 numbers, once 7 numbers, once 3 numbers and not exactly 9 numbers. Why?
private static Set<Integer> losowanie() {
Set<Integer> result = new TreeSet<>();
Random random = new Random();
for (int i = 0; i < 10; i++){
result.add(random.nextInt(10) + 1);
}
return result;
}
}
also i was doing the same thing with while loop and it does the same.
Because Set collections cannot have duplicate properties, that is, when you generate numbers, if the same number is generated in the random number, your Set can only hold a unique number.
public static void main(String[] args) {
Set<Integer> result=new TreeSet<>();
for (int i = 0; i < 10; i++) {
result.add(1);
}
//only one data: [1]
System.out.println(result);
result=new TreeSet<>();
for (int i = 0; i <10 ; i++) {
result.add(i);
}
//ten data:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
System.out.println(result);
}
First of all, your loop indexes from 0 to 9, and that's ten iterations.
So, you might expect ten numbers in your set. But set elements have to be unique, and you are inserting elements randomly selected from a set of only ten possibilities.
The chances of that happening are 10! รท 1010 or about 0.036%. Keep running your program.
If your goal is to have ten different numbers in a random order, do this instead:
List<Integer> result = IntStream.rangeClosed(1, 10)
.boxed()
.collect(Collectors.toList());
Collections.shuffle(random);
I need to write a program that checks if the boys (3) are arranged in ascending or descending order by height.
I can use 3 times scanner.nextInt():
int a = scanner.nextInt();
than use if statement :
if (a >= b && b >= c || c >= b && b >= a) {
System.out.println("true");
} else {
System.out.println("false");
}
And it's work perfectly.
I also can create an array and check it, but it's not interesting. But I want to try to solve it using for loop for scanning input values within loop and check conditions:
final int numberOfBoys = 3;
boolean result = false;
for (int i = 0; i < numberOfBoys; i++) {
int boyHeight = scanner.nextInt();
int a = boyHeight;
if (a >= boyHeight || a <= boyHeight) {
result = true;
}
}
System.out.println(result);
Here I assigned input value of boyHeight to a variable and compare it with next scanning value, but I always get true result which is wrong.
Here is a way to determine if all three are in descending order, ascending order, or not in order at all.
1. Scanner scanner = new Scanner(System.in);
2. int[] heights = new int[3];
3. heights[0] = scanner.nextInt();
4. heights[1] = scanner.nextInt();
5. heights[2] = scanner.nextInt();
6.
7. if (heights[0] >= heights[1] && heights[1] >= heights[2]) {
8. System.out.println("descending order");
9. } else if (heights[0] <= heights[1] && heights[1] <= heights[2]) {
10. System.out.println("ascending order");
11. } else {
12. System.out.println("not in order");
13. }
A few notes:
line 2: this is hard-coded to 3, obviously it wouldn't work if you want to compare with 4 or some other number
lines 3-5: also hard-coded to 3, but easily could be moved into a loop
line 7: if item 0 is larger than 1, and 1 is larger than 2, that's clearly "descending". This could be reworked to fit with a loop, but it's perhaps clearer to see this way.
line 9: similar to 7, just compare the other direction
line 12: this is the case for mixed ordering, neither ascending nor descending
If you want to use a loop, here's an edit to replace lines 2-5:
int totalToCheck = 3;
int[] heights = new int[totalToCheck];
for (int i = 0; i < totalToCheck; i++) {
heights[i] = scanner.nextInt();
}
Checking if an Array is in Ascending or Descending order in a loop
I want to try solve it using for scanning input values within loop
Solution below allow to determine whether array the order of an array of an arbitrary length without using hard-coded conditions.
Note that storing the user input into an array simultaneously with checking if this array is order violate the first SOLID principle - the Single responsibility principle. The correct way to do that is to first read the array data from the console (which is pretty trivial) and then determine whether this array is ordered - that is the focus of this answer.
Regardless of the number of elements in the array there could be the following cases:
Array is sorted in Ascending order;
Array is sorted in Descending order;
Array is unordered;
Since equal values are allowed there could be the case when all elements are equal, i.e. we can't say array is unordered, but at the same it is neither ascending, no descending.
I'm also making an assumption that the given will contain at least 1 element.
public static void determineArrayOrder(int[] arr) {
boolean isAsc = arr[0] < arr[arr.length - 1]; // if array is sorted in ascending order the first element has to be less than the last element
int previous = arr[0]; // variable that would hold the value of the previously encountered element
for (int i = 1; i < arr.length; i++) { // iteration starts from 1 because `previous` has been initialized with the value of the element at index 0
int next = arr[i];
if (next < previous && isAsc || next > previous && !isAsc) { // the order doesn't match
System.out.println("Array is unordered");
return;
}
previous = next;
}
// printing the result
if (arr[0] == arr[arr.length - 1]) {
System.out.println("impossible to determine the order");
} else if (isAsc) {
System.out.println("Array is sorted in Ascending order");
} else {
System.out.println("Array is sorted in Descending order");
}
}
main()
public static void main(String[] args) {
determineArrayOrder(new int[]{1, 2, 3, 3, 3}); // ASC
determineArrayOrder(new int[]{7, 5, 3, 3, 5}); // unordered
determineArrayOrder(new int[]{7, 8, 9, 8, 8}); // unordered
determineArrayOrder(new int[]{7, 5, 3, 3, 1}); // DSC
determineArrayOrder(new int[]{9, 9, 9, 9, 9}); // impossible to determine the order
}
Output:
Array is sorted in Ascending order
Array is unordered
Array is unordered
Array is sorted in Descending order
impossible to determine the order
Another way of doing this on the fly is
Read the number of elements (input validation at least 2 values)
Check first 2 values to get the order
Iterate the rest of elements and check if the order is the same
Display the result
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Input numbers: ");
int numberOfBoys = scanner.nextInt(); // Read the number of elements in the array
if (numberOfBoys < 2) { // Validate the input
System.out.println("Invalid input");
}
boolean isAsc = false; // Assume that the sequence is DESC
boolean isValid = true; // Assume that the sequence is valid
int previousRead = scanner.nextInt(); // Read first value
int currentRead = scanner.nextInt(); // Read second value
if (previousRead < currentRead) { // Check if the first 2 values are ASC
isAsc = true; // Correct our assumption
}
previousRead = currentRead; // Swap the values to prepare for the next read
// Iterate through the rest of the sequence
for (int i = 0; i < numberOfBoys - 2; i++) {
currentRead = scanner.nextInt(); // Read the next value
// Check if the new value respect the order
isValid = isAsc ? currentRead >= previousRead : currentRead <= previousRead;
// if the new value does not follow the order,
// breaks the loop because we already know the answer and
// there is no point in reading the rest of the values
if (!isValid) {
break;
}
previousRead = currentRead; // Swap the values to prepare for the next read
}
// Print the conclusion
if (isValid) {
if (isAsc) {
System.out.println("ASC");
} else {
System.out.println("DESC");
}
} else {
System.out.println("Unsorted");
}
}
This question already has answers here:
How to merge two sorted arrays into a sorted array? [closed]
(30 answers)
Closed 5 years ago.
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arrA = {2,3,4};
int[] arrB = {5,6,7,8};
mergeArray(arrA,arrB);
}
static void mergeArray(int[] arrA,int[] arrB){
int len = arrA.length+arrB.length;
int lenA = arrA.length;
int lenB = arrB.length;
int a=0,b=0,c=0;
int temp=0;
int[] arrC = new int[len];
for(int i=0; i < lenA; i++){
arrC[i] = arrA[i];
}
for(int j=lenA,k=0; (k < lenB) && (j < len) ; j++,k++){
arrC[j] = arrB[k];
}
for(int n=0; n < len ; n++){
for(int m=0; m < len; m++ ){
if(arrC[n] < arrC[m]){
temp = arrC[n];
arrC[n] = arrC[m];
arrC[m] = temp;
}
}
}
for(int x : arrC){
System.out.println(x);
}
}
Result: {2,3,4,5,6,7,8}
I am trying to put the values into one new array and sorting them again.Can any one give me better solution than this.
I recalled old school days! Here is the solution! No libraries, just plain code! Enjoy.
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int [] array1 = {5, 1, 4, 5, 7, 8, 1, 0, 4};
int [] array2 = {4, 7, 1, 0, 9, 3};
System.out.println("Array 1");
print(array1);
System.out.println("Array 2");
print(array2);
Arrays.sort(array1);
Arrays.sort(array2);
System.out.println("Sorted array 1");
print(array1);
System.out.println("Sorted array 2");
print(array2);
int [] mergedAndSortedArray = mergeSorted(array1, array2);
System.out.println("Sorted merged array");
print(mergedAndSortedArray);
}
private static void print(int [] array) {
for (int i : array) {
System.out.print(i + " ");
}
System.out.println("\n");
}
private static int [] mergeSorted(int [] array1, int [] array2) {
int [] res = new int [array1.length + array2.length];
int i = 0;
int j = 0;
int k = 0;
//Do your homework. First loop until you reach end of either array, and then add the rest elements.
return res;
}
}
This is result
Array 1
5 1 4 5 7 8 1 0 4
Array 2
4 7 1 0 9 3
Sorted array 1
0 1 1 4 4 5 5 7 8
Sorted array 2
0 1 3 4 7 9
Sorted merged array
0 0 1 1 1 3 4 4 4 5 5 7 7 8 9
Update
If you need to merge N sorted arrays into a sorted one, you can merge them by pairs recursively (merge first and second arrays, third and fourth, and so on), then again, until you have two arrays, and finally merge them too!
You can use Java8 Streams:
int[] arrA = {2,3,4};
int[] arrB = {5,6,7,8};
int[] mergedArray = IntStream.concat(Arrays.stream(arrA), Arrays.stream(arrB)).toArray();
If the order is important:
IntStream.concat(Arrays.stream(arrA), Arrays.stream(arrB)).sorted().toArray();
In such case you can convert it not only to an array, but to whatever you want.
Easy. You're concatenating one array after another, then doing a bubble sort. A bubble sort is O(n^2) in the worst case. This means that the time needed to sort may increase with the square of the sum of the lengths of the two input arrays.
But you already know that the two arrays are ordered. When writing to the combined array, all you need to look at are the heads of the two input arrays. The next write will be the minimum value of the two. Your merge will be O(n), where n is the sum of the lengths of the two input arrays.
This is one part of a sorting algorithm called merge sort. Frequently a merge sort is in-place, in a single array. Yours differs slightly, with the two sorted parts in separate arrays, but the idea is the same.
Try this:
Integer[] mergeArray = (Integer[])ArrayUtils.addAll(arrA, arrB);
Checkout this:
public static T[] addAll(T[] array1, T... array2)
And then:
Arrays.sort(mergeArray, Collections.reverseOrder());
I think you're asking for a way to "zip together" two arrays that are already sorted, so that you end up with a sorted array. I think you've realised that concatenating then sorting is inefficient, because it doesn't take advantage of the input arrays being sorted already.
I also assume that this is a homework or study question, so I'm going to describe the solution at a high level.
You need a few variables to track where you are:
leftIndex (where you are on the left input)
rightIndex (where you are on the right input)
destinationIndex (where you are in the destination)
Start with all the indexes at zero. Now we're going to pick an array to work from, and take values from it one by one.
As long as those values are less than the next value from the other input array, we add it to the output. Then we switch over to the other array. We keep switching back and forth until we've reached the end of both inputs.
Pseudocode:
while (leftIndex and rightIndex are both within the length of their arrays) {
while(leftInput[leftIndex] is less than rightInput[rightIndex]) {
copy leftInput[leftIndex] into destination[destinationIndex]
increment leftIndex
increment destinationIndex
}
while(rightInput[rightIndex] is less than leftInput[leftIndex]) {
copy rightInput[leftIndex] into destination[destinationIndex]
increment rightIndex
increment destinationIndex
}
}
If you translate what I've written directly into Java, you'll probably get ArrayIndexOutOfBounds exceptions. You need to add extra code in the while statement to make it do the right thing when one of the indexes is past the end of its array.
This question already has answers here:
Generating Unique Random Numbers in Java
(21 answers)
Closed 6 years ago.
for (int x = 0 ; x < chosenQ.length ; x++)
{
chosenQ [x] = r.nextInt (9);
c.println (chosenQ [x]);
}
This generates 5 ints between 0 and 9. How do i make it so it will not have duplicate ints when generating it?
Create an array with 10 elements from 0 to 9
Shuffle the array
Take the first five elements
In pseudo code
array = [0, 1, ..., 9]
array.shuffle.take(5)
You'll have to keep a record of which numbers were chosen already.
One way you can do that is by storing the values in a boolean array where all values are initialized to false. When a random value is generated, the element at that index is set to true. Then, for each generated number, you can simply check if the element at that index is true or false.
For example,
// array of booleans initialized to false
boolean[] array = new boolean[chosenQ.length];
for (int x = 0 ; x < chosenQ.length ; x++)
{
int i = r.nextInt(9);
// check if value was chosen already
while (array[i] == true)
i = r.nextInt(9);
// set generated value's index in array to true
array[i] = true;
chosenQ[x] = i;
c.println(chosenQ[x]);
}
my main purpose is to get this kind of a output: which shows the value and the number of times it appears in a array. Below is an example, but during the code, i will ask the user for input of data integers into an array
e.g. for the array: {-12, 3, -12, 4, 1, 1, -12, 1, -1, 1, 2, 3, 4, 2, 3, -12}
The output should be:
N Count
4 2
3 3
2 2
1 4
-1 1
-12 4
below here is my own attempt, but for some reason i could not get the array to be stored, and used at other parts of the code:
import java.util.*;
public class Q4
{
/**
* #param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
int[] myarray = new int[50];
System.out.println("Enter integers into the system, to quit enter -99");
Scanner scan=new Scanner(System.in);
for(int i = 0; i<myarray.length; i++)
{
int temp =scan.nextInt();
if(temp!=(-99))
{
myarray[i]=temp;
}
if(temp ==(-99))
{
System.out.println("Successfully terminated by inputting -99");
System.out.println();
break;
}
else if(i==(myarray.length-1))
{
System.out.println("successfully filled up array fully");
System.out.println();
}
}
for(int i = 0; i<myarray.length; i++)
{
System.out.print(myarray[i]+",");
}
System.out.print("}");
int temp=0;
int number = 0;
Arrays.sort(myarray);
System.out.println("Array list: {");
for (int i = 0; i < myarray.length; i++)
{
if(temp==0)
{
temp=myarray[i];
number++;
}
else if (temp!=0)
{
if (temp==myarray[i])
{
number++;
}
else
{
temp=0;
}
}
}
System.out.print("}");
System.out.println();
System.out.println();
System.out.println("N"+"\t"+"\t"+"Count");
System.out.println(temp+"\t"+"\t"+number);
}
}
here is My output, which isnt what i wanted,
Enter integers into the system, to quit enter -99
12
3123
3123
11
22
-99
Successfully terminated by inputting -99
Array list: {12,3123,3123,11,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}Array list: {
}
N Count
3123 48
You increment number to attempt to count how many times the current array[i] has been seen, yet you never reset it's value to 0.
Also, at the end of your method, you are only printing a single row of the N Count table. If you want to print one row for each unique element of the index, don't you need to print more than one row?
There's an easier way to count the occurrences of elements in an array that doesn't require sorting it - hint, considering using a Map<Integer, Integer>.
You should try following thing.
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Scanner;
public class NumberRepetion {
public static void main(String[] args) {
int[] myarray = new int[50];
System.out.println("Enter integers into the system, to quit enter -99");
Scanner scan = new Scanner(System.in);
ArrayList<Integer> myarrList = new ArrayList<Integer>();
while (scan.hasNext()) {
int temp = scan.nextInt();
if (temp != (-99)) {
// myarray[i] = temp;
myarrList.add(temp);
}
if (temp == (-99)) {
System.out.println("Successfully terminated by inputting -99");
System.out.println();
break;
}
}
Hashtable<Integer, Integer> result = new Hashtable<Integer, Integer>();
System.out.print("Input Values {");
int currIndex = 0 ;
for (Integer val : myarrList) {
if (currIndex == ( myarrList.size() - 1 )){
System.out.print(val);
}else{
System.out.print(val + ", ");
}
currIndex++ ;
int currVal = val;
Integer integer = result.get(currVal);
if (integer == null || integer == 0) {
result.put(currVal, 1);
} else {
result.put(currVal, ++integer);
}
}
System.out.print("}");
System.out.println()
Enumeration<Integer> keys = result.keys();
System.out.println("N\t\tCount");
while(keys.hasMoreElements()){
System.out.println(" " + keys.nextElement() +"\t\t" + result.get(keys.nextElement()));
}
//System.out.println("\n\n\n Result " + result);
}
}
OUTPUT
Enter integers into the system, to quit enter -99
5
6
5
8
4
-99
Successfully terminated by inputting -99
Input Values {5, 6, 5, 8, 4}
N Count
8 1
5 1
What I would do is to make a new node class that has two instances, the value and count. Every time you encounter a new number, make a new node with the its value, and increment its count by one. Have a List of the nodes and add the node to this list. For the next input, have a loop check if the value has already been seen before, eg.
for i = 0; i <list.size; i++
if list.get(i).data == value // if it finds the value increment and break
list.get(i).count++
break;
else if i==list.size-1//if it went through the list and didn't find the value, make a new node of the value and add it to the list
make a new node
add it to the list
After it has terminated, sort the list by comparing list.get(i).values and swapping (bubble sort comes to mind but there are many ways to sort)
After that just print the values and it's count
If this isn't a lesson how to use Arrays, I strongly advocate in making contact with List, and other collections - but preferably List, and concretely ArrayList. It is so convenient! And it is easy.
There are 3 or 4 basic operations: Constructor to define a List, add elements, remove elements, iterate over all elements.
And about 50 other not so frequently used methods, and methods which use Lists and so on.
public static void main (String [] args)
{
List <Integer> myarray = new ArrayList <Integer> ();
System.out.println ("Enter integers into the system, to quit enter -99");
Scanner scan = new Scanner (System.in);
while (scan.hasNextInt ())
{
int temp = scan.nextInt ();
if (temp == -99)
{
System.out.println ("Successfully terminated by inputting -99");
System.out.println ();
break;
}
else {
myarray.add (temp);
if (myarray.size () == 50)
{
System.out.println ("successfully filled array fully up");
System.out.println ();
}
}
}
for (int i : myarray)
{
System.out.print (i + ",");
}
System.out.print ("}");
Set <Integer> hsi = new HashSet <Integer> ();
hsi.addAll (myarray);
Collections.sort (myarray);
System.out.println ("Array list: {");
int idx = 0;
for (int i: hsi) {
System.out.println (i + "\t" + Collections.frequency (myarray, i));
}
System.out.println (myarray.size ());
}
See how short and simple? Just add the elements - you don't need to know in advance how many elements it contains. No marker-fields or external values to mark the end necessary!
Usage:
java Numbers
Enter integers into the system, to quit enter -99
4 44 0 33 2 2 7 9 1 4 3 90 -99
Successfully terminated by inputting -99
4,44,0,33,2,2,7,9,1,4,3,90,}Array list: {
0 1
1 1
2 2
3 1
33 1
4 2
7 1
9 1
44 1
90 1
12
Your first idea for collecting values, you like to get by index or you want to iterate over, should be ArrayList, not a plain old array. Array is only useful in exceptional cases - when you surely know the size in advance to begin with.
ArrayLists are fast, believe it - no - don't believe it, test it!