I am using Java Arrays.sort in order to sort elements of a two dimensional array:
int[][] RAM = new int[4][10000];
I fill the RAM array with integers and then call:
for (i=0;i<4;i++){
Arrays.sort(RAM[i]);
System.out.println(i);
}
This results in all elements of RAM[][] being filled with zeros. What am I doing wrong?
Did you actually fill the Array with numbers first?
And if you did, you are only printing out the First part of your 2D array. You need to print out all 40,000 entries. 10,000 for each array in array. So [0][0...9999], [1][0...9999] etc.
public static void show (int [][] list)
{
System.out.println ("- show: -");
for (int [] ia : list) {
for (int i : ia)
System.out.print (i + ", ");
System.out.println ();
}
System.out.println ("---");
}
static Random random = new Random ();
public static void main (String [] args)
{
int[][] RAM = new int[4][2];
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 2; ++j)
{
RAM[i][j] = random.nextInt (20);
System.out.print (i*2 +j);
}
}
show (RAM);
for (int i=0; i<4; i++) {
Arrays.sort (RAM[i]);
}
show (RAM);
System.out.println ();
}
Result:
- show: -
8, 13,
12, 10,
16, 3,
7, 1,
---
- show: -
8, 13,
10, 12,
3, 16,
1, 7,
---
I think the reason is that you didn't set a value for all elements of your array. For the item you didn't initialize, the default value is 0. Thus when you sort the all items in the array, the 0s are swapped to the first part of your array. If you output the first parts of the array, all you see are zeros. I guess so.
Related
I'm trying to get the N smallest numbers (given by the user) in an array without using methods like sort()... in the last step, I keep getting only the smallest values and 0 for the rest.. where's the problem?
//1- Scanner to take inputs
Scanner input = new Scanner(System.in);
//2- Take the array size as input and store it in "sizeOfArr" var
System.out.print("Enter the array size: ");
int sizeOfArr = input.nextInt();
//3- Assign the input as an array size
int array[] = new int[sizeOfArr];
//4- Looping on the array and update its values by inputs taken from the user
for(int i = 0; i < array.length; i++) {
System.out.print("Enter "+ (i+1) + "-st element: ");
array[i] = input.nextInt();
}
//5- Print out the array after convert it to String
System.out.println(Arrays.toString(array));
//6- Find the smallest element in the array and print it
int minVal = array[0];
for(int i = 0; i < array.length; i++) {
if (array[i] < minVal) {
minVal = array[i];
}
}
// System.out.println(minVal);
//7- Find the (n) smallest of number defined by the user
System.out.print("Enter the number of smallest numbers do you want: ");
int n = input.nextInt();
//8- new array to store n smallest numbers
int smallestNums[] = new int[n];
//9- trying to loop on the original array n times
int counter;
for(int i = 0; i < n ; i++) {
//10- trying to loop on the original array to store the smallest values in smallestNum[] array.
for(int j = 0; j < array.length; j++) {
smallestNums[i] = minVal;
}
if(smallestNums[i] == smallestNums[i]) {
break;
}
}
System.out.println(Arrays.toString(smallestNums));
Here is one way. Just do a partial sort with the outer loop limit equal to the number of items required. This is variant of the selection sort. This example, varies n in the outer list for demo purposes.
int[] array = { 10, 1, 5, 8, 7, 6, 3 };
for (int n = 1; n <= array.length; n++) {
int[] smallest = getNSmallest(n, array);
System.out.printf("smallest %2d = %s%n", n,
Arrays.toString(smallest));
}
prints
smallest 1 = [1]
smallest 2 = [1, 3]
smallest 3 = [1, 3, 5]
smallest 4 = [1, 3, 5, 6]
smallest 5 = [1, 3, 5, 6, 7]
smallest 6 = [1, 3, 5, 6, 7, 8]
smallest 7 = [1, 3, 5, 6, 7, 8, 10]
Here is the method. The first thing to do is copy the array so the
original is preserved. Then just do the sort and return array of smallest elements.
public static int[] getNSmallest(int n, int[] arr) {
int[] ar = Arrays.copyOf(arr, arr.length);
int[] smallest = new int[n];
for (int i = 0; i < n; i++) {
for (int k = i + 1; k < ar.length; k++) {
if (ar[i] > ar[k]) {
int t = ar[i];
ar[i] = ar[k];
ar[k] = t;
}
}
smallest[i] = ar[i];
}
return smallest;
}
For this task, you don't have to sort the whole array. Only a group of N elements has to be sorted. I.e. only a partial sorting is required.
Below, I've provided two implementations for this problem. The first utilizes only plane arrays and loops, the second makes use of the PriorytyQueue.
The first solution maintains a variable pos which denotes the position in the result array which isn't assigned yet. Note that the default value for an element of the int[] is 0. It's important to be able to distinguish between the default value and a zero-element from the given array. Hence we can't rely on the values and have to track the number of elements that are assigned.
Every element of the source array gets compared with all the elements of the result array that are already assigned. The new element will be added to the result array in two cases:
nested loop has reached an unoccupied position pos in the result array;
an element in the result array that is greater than the next element from the given array has been found.
In the first case, a new element gets assigned the position denoted by pos. In the second case, a new element has to be inserted
nested loop iterates over the given array at the current position i and all elements must be shifted to the right. That's what the method shiftElements() does.
The First solution - Arrays & Loops
public static int[] getSmallest(int[] arr, int limit) {
int[] result = new int[Math.min(limit, arr.length)];
int pos = 0;
for (int next: arr) {
for (int i = 0; i < Math.min(pos + 1, result.length); i++) {
if (i == pos) result[i] = next;
else if (result[i] > next) {
shiftElements(result, next, i, Math.min(pos + 1, result.length));
break;
}
}
pos++;
}
return result;
}
private static void shiftElements(int[] arr, int val, int start, int end) {
int move = arr[start];
arr[start] = val;
for (int i = start + 1; i < end; i++) {
int temp = arr[i];
arr[i] = move;
move = temp;
}
}
Maybe you'll be more comfortable with the first version, but if you are somehow familiar with the Collections framework, then it's a good time to get acquainted with PriorytyQueue. In the nutshell, this collection is backed by an array and maintains its element in the same order as they were added, but when an element is being deleted collection retrieves the smallest one according to the natural order or based on the Comparator, which can be provided while instantiating the PriorytyQueue. It uses a sorting algorithm that is called a heapsort which allows removing a single element in O(log N) time.
The Second solution - PriorytyQueue
public static int[] getSmallestWithPriorityQueue(int[] arr, int limit) {
Queue<Integer> queue = new PriorityQueue<>();
populateQueue(queue, arr);
int[] result = new int[Math.min(limit, arr.length)];
for (int i = 0; i < result.length; i++) {
result[i] = queue.remove();
}
return result;
}
private static void populateQueue(Queue<Integer> queue, int[] arr) {
for (int next: arr) {
queue.add(next);
}
}
main & utility-method to generate an array
public static void main(String[] args) {
int[] source = generateArr(100, 10);
System.out.println("source : " + Arrays.toString(source));
int[] result1 = getSmallest(source, 3);
System.out.println("result(Arrays & Loops) : " + Arrays.toString(result1));
int[] result2 = getSmallestWithPriorityQueue(source, 3);
System.out.println("result(PriorityQueue) : " + Arrays.toString(result2));
}
public static int[] generateArr(int maxVal, int limit) {
Random random = new Random();
return IntStream.generate(() -> random.nextInt(maxVal + 1))
.limit(limit)
.toArray();
}
output
source : [61, 67, 78, 53, 74, 51, 50, 83, 59, 21]
result(Arrays & Loops) : [21, 50, 51]
result(PriorityQueue) : [21, 50, 51]
Randomized select allows to find k-th ranked element in linear time on average.
It alters the input order, so practically, it makes sense to just sort and return k-th element of the sorted array. Especially if there are several such calls on the given input array.
I need to write a code that will display the last three elements of an array using for loop. 1. The arrays size can be modified and the code should cope with that. 2. The elements should be displayed as they were entered (from left to right).
import java.util.Arrays;
public class Task4 {
public static void main(String[] args) {
int[] array = {7, -3, 9, -11, 18, 99, 2, 11};
System.out.println("Current array: " + Arrays.toString(array));
System.out.println("Last three elements of an array: ");
for (int i = array.length / 2 + 1; i < array.length; i++) {
System.out.print(array[i] + " ");
/*need to display last three elements of an array using for loop.
the elements should be displayed as they were entered(from left-to-right)*/
}
}
}
The code works only for this specific array. My question was is there any alternative solutions that will work for any array size?
you can try to start from the index that equals the length-3 by changing the loop into this :
for (int i = Math.max(0,array.length-3); i < array.length; i++) {
A java stream option here:
IntStream.of(array)
.skip(Math.max(array.length - 3, 0))
.forEach(System.out::println);
I have two arrays. Array1 holds 5 randomly generated numbers and array2 holds 5 guesses inputted by the user. I'm trying to count the matches but the only matches that are being read are the ones in the same position. How can I get my program to count the same number even if it's in a different position?
Here's what I've got so far:
int count = 0;
for (i=0;i<array1.length;i++){
if(array1[i] == array2[i]){
count = count +1;
}
}
System.out.println("matching numbers : "+count);
If the two arrays are both small, i.e. each array contains only five elements, then you need a nested loop. For each element in the random numbers array, iterate through the guesses array.
int count = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array2.length; j++) {
if (array1[i] == array2[j]) {
count++;
}
}
}
System.out.println("matching numbers : "+count);
Note that the above is appropriate when both arrays are small. When both arrays are large the above is not appropriate.
You just need the intersection between the two arrays and then to count the size of the result array.
So you can avoid to manually loop over the two arrays just simply using the retainAll method on List class:
https://docs.oracle.com/javase/7/docs/api/java/util/List.html#retainAll
Here is a junit test that shows how to solve using this approach:
#Test
public void TestArraysIntersection() {
Integer[] randomlyGenerated = {1,2,3,4,5};
Integer[] userInput = {4,2,5,3,6};
System.out.println("Randomly generated numbers are: " + Arrays.toString(randomlyGenerated));
System.out.println("Number selected by the user are: " + Arrays.toString(userInput));
List<Integer> intersectionList = new ArrayList<>(Arrays.asList(randomlyGenerated));
intersectionList.retainAll(Arrays.asList(userInput));
System.out.println("Matching numbers are " + intersectionList.size() + " and the values are: "+ intersectionList);
}
Test result is the following:
Randomly generated numbers are: [1, 2, 3, 4, 5]
Number selected by the user are: [4, 2, 5, 3, 6]
Matching numbers are 4 and the values are: [2, 3, 4, 5]
You need to loop through both arrays. In your code you are comparing each element of one array with the element in the same position of the other array, but you have to compare each element of one array with every element of the other array, like this:
public class MyClass {
public static void main(String args[]) {
int[] numbers = {1, 3, 0, 6};
int[] guesses = {3, 8, 5, 1, 2};
for (int i = 0; i < numbers.length; i++) {
for (int j = 0; j < guesses.length; j++) {
if (numbers[i] == guesses[j]) {
System.out.println("A match on positions "+i+" and "+j+". "+numbers[i]+" = "+guesses[j]);
}
}
}
}
}
Output:
A match on positions 0 and 3. 1 = 1
A match on positions 1 and 0. 3 = 3
Of course, instead of outputting the values that match, you can instead increment a count like in your example, and show instead how many elements matched.
The idea is to have a two dimensional array NxN where all the elements (numbers from 0 to N*N) are in random positions. To generate the random numbers I used:
// Creates a set so we avoid repetition of generated numbers
Set<Integer> generatedNumbers = new LinkedHashSet<Integer>();
while (generatedNumbers.size() < numberOfElements){
Integer next = rng.nextInt(numberOfElements) ;
generatedNumbers.add(next);
}
Now I need to copy the elements to a two dimensional array. Basically, something like this:
for (Integer number: generatedNumbers){
// Here I'd like to have:
// 1st iteration: board[0][0] = number
// 2nd iteration: board[0][1] = number
// ...
// last iteration: board[3][3] = number
}
where:
board = new int[boardSize][boardSize];
with boardSize = 4 for this particular case.
Btw, if there's a better way to achieve the same but using a different method, I'd be happy to read it.
If I understood correctly you want to randomly distribute numbers from a collection into a 2d array. Here is a working code based on what you gave us that will do just that:
public static Integer[][] getRandomNumbersArray(int base)
{
Random rng = new Random();
int numberOfElements = base * base;
// Let's use a list so we access by index
List<Integer> generatedNumbers = new ArrayList<>();
for (int i = 0; i < numberOfElements; i++)
{
// Generate our random number
Integer next = rng.nextInt(numberOfElements) ;
// Check if the number is already added
if (!generatedNumbers.contains(next)) {
generatedNumbers.add(next);
}
// Number was a duplicate, redo loop cycle
else i--;
}
// Create our board array here
Integer[][] array = new Integer[base][base];
// Index used to access the list
int i1 = 0;
for (int i2 = 0; i2 < base; i2++)
{
// Populate board row
for (int i3 = 0; i3 < base; i3++, i1++) {
array[i2][i3] = generatedNumbers.get(i1);
}
}
return array;
}
public static void main(String[] args)
{
Integer[][] array = getRandomNumbersArray(4);
System.out.println("Here is how our board looks like:");
for (int i = 0; i < array.length; i++) {
System.out.println(Arrays.toString(array[i]));
}
}
Output
Here is how our board looks like:
[8, 7, 11, 3]
[15, 5, 1, 0]
[2, 9, 10, 12]
[13, 4, 6, 14]
Instead of iterating the set on the outside of the loop, consider doing it in reverse. Something along the lines of
Iterator iter = generatedNumbers.iterator()
for (...) {
for (...) {
if (iter.hasNext()) arr[i][j] = iter.next()
else ...
}
}
I have to perform the following basic skills with arrays: Here is a list of everything I had to do:
a) Create an array x of doubles with an initializer list that contains the following values: 8, 4, 5, 21, 7, 9, 18, 2, and 100.
b) Print the number of items in the array.
c) Print the first array item.
d) Print the last array item. Be careful to choose the right index.
e) Use a standard for loop to print all the values in the array.
f) Use a standard for loop to print all the values in the array with labels to indicate the location of each element, such as [0] = xx
g) Use a standard for loop to print all the values in the array in reverse order.
h) Use an enhanced for loop to print all the values in the array.
I am having a lot of trouble with f), I saw that you could label using "JLabel" which I did not learn in my class but I wasn't sure if it could be applied here, here is my code so far. If "JLabel" can't be used, what else would I be able to do? Any help will be appreciated, Thanks!!!
public static void main(String[] args) {
double[] x = {8, 4, 5, 21, 7, 9, 18, 2, 100};
double temp;
System.out.println("The number of items in the array is " + x.length);
System.out.println("The first array item is " + x[0]);
System.out.println("The last array item is " + x[8]);
for(int i = 0; i < 9; i++)
{
System.out.println(x[i] + " ");
}
//F
//JLabel labels[] = new JLabel[8];
//for (int i = 0; i < 9; i++)
//{
//labels[i] = new JLabel("Label" + i);
//}
for(int i =x.length - 1; i >= 0; i--)
{
System.out.println(x[i] + " ");
}
for (double val : x)
{
System.out.println(val + " ");
}
}
}
JLabel is a Swing GUI component. It represents a text label in a GUI. It is not what you want to use here (although I can understand your attraction to the "Label" in its name -- but, you don't make ham with a hammer).
Your requirement is simply "print all the values in the array with labels to indicate the location of each element, such as [0] = xx". That is, "labels" in the dictionary sense, not "labels" as in some explicit special "label" class.
It's simpler than you think, you may be over-complicating this! For example:
for (int i = 0; i < x.length; i ++) {
// 'i' is the index
// 'x[i]' is the value
System.out.println( /* fill this in */ );
}
I'll leave the details as an exercise to you. Hint: If i==1 and x[i]==42 then the output should be [1] = 42.