Need help understanding segment of code - java

public int[] selectionSort(int array[]) {
for(int i = array.length - 1; i >= 0; i--) {
int highestIndex = i;
for(int j = i; j >= 0; j--) {
if(array[j] > array[highestIndex])
highestIndex = j;
}
int temp = array[i];
array[i] = array[highestIndex];
array[highestIndex] = temp;
}
return array;
}
I understand the concept of selection sort, but the code is confusing me. Specifically, can someone explain what is happening in the last three statements of the outer for-loop starting with "int temp = array[i];"

This is the famous swapping routine. In languages like Java, when you want to swap the values of two variables named say a and b, you have to resort to such a routine where you use a third variable to hold a value in transit:
int a = 2;
int b = 6;
int tmp = a; // now tmp has a value that is _copy_ of a i.e. 2
a = b; // since we saved a in tmp, we can _mutate_ it, now a has b's value
b = tmp; // swap! here, b = a won't work because a contains b's current value.
// now a has value 6 and b has value 2, exactly what we wanted.
In some other languages, a construct like a, b = b, a is available for this purpose, which is more intuitive in my opinion.
In selection sort, after the inner loop has found the index of the element that holds the highest value, you need to swap it with the element held by the outer loop index and that's what this achieves in that context.

Related

Trying to create a array with the intersection of two arrays but fails at creating array with the proper structure

So, I am trying to create 2 randomly generated arrays,(a, and b, each with 10 unique whole numbers from 0 to 20), and then creating 2 arrays with the info of the last two. One containing the numbers that appear in both a and b, and another with the numbers that are unique to a and to b. The arrays must be listed in a "a -> [1, 2, 3,...]" format. At the moment I only know how to generate the 2 arrays, and am currently at the Intersection part. The problem is, that I can create a array with the correct list of numbers, but it will have the same length of the other two, and the spaces where it shouldn't have anything, it will be filled with 0s when its supposed to create a smaller array with only the right numbers.
package tps.tp1.pack2Arrays;
public class P02ArraysExtractUniqsAndReps {
public static void main(String[] args) {
int nbr = 10;
int min = 0;
int max = 20;
generateArray(nbr, min, max);
System.out.println();
}
public static int[] generateArray(int nbr, int min, int max) {
int[] a = new int[nbr];
int[] b = new int[nbr];
int[] s = new int[nbr];
s[0] = 0;
for (int i = 0; i < a.length; i++) {
a[i] = (int) (Math.random() * (max - min));
b[i] = (int) (Math.random() * (max - min));
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
i--;
}
if (b[i] == b[j]) {
i--;
}
}
}
System.out.println("a - > " + Arrays.toString(a));
System.out.println("b - > " + Arrays.toString(b));
for (int k = 0; k < a.length; k++) {
for (int l = 0; l < b.length; l++) {
if (a[k] == b[l]) {
s[l] = b[l];
}else {
}
}
}
System.out.println("(a ∪ (b/(a ∩ b)) - > " + Arrays.toString(s));
return null;
}
public static boolean hasValue(int[] array, int value) {
for (int i = 0; i < array.length; i++) {
if (array[i] == value) {
return true;
}
}
return false;
}
}
Is there any way to create the array without the incorrect 0s? (I say incorrect because it is possible to have 0 in both a and b).
Any help/clarification is appreciated.
First, allocate an array large enough to hold the intersection. It needs to be no bigger that the smaller of the source arrays.
When you add a value to the intersection array, always add it starting at the beginning of the array. Use a counter to update the next position. This also allows the value 0 to be a valid value.
Then when finished. use Array.copyOf() to copy only the first part of the array to itself, thus removing the empty (unfilled 0 value) spaces. This works as follow assuming count is the index you have been using to add to the array: Assume count = 3
int[] inter = {1,2,3,0,0,0,0};
inter = Arrays.copyOf(inter, count);
System.out.println(Arrays.toString(inter);
prints
[1,2,3]
Here is an approach using a List
int[] b = {4,3,1,2,5,0,2};
int [] a = {3,5,2,3,7,8,2,0,9,10};
Add one of the arrays to the list.
List<Integer> list = new ArrayList<>();
for(int i : a) {
list.add(i);
}
Allocate the intersection array with count used as the next location. It doesn't matter which array's length you use.
int count = 0;
int [] intersection = new int[a.length];
Now simply iterate thru the other array.
if the list contains the value, add it to the intersection array.
then remove it from the list and increment count. NOTE - The removed value must be converted to an Integer object, otherwise, if a simple int value, it would be interpreted as an index and the value at that index would be removed and not the actual value itself (or an Exception might be thrown).
once finished the intersection array will have the values and probably unseen zeroes at the end.
for(int i = 0; i < b.length; i++) {
int val = b[i];
if (list.contains(val)) {
intersection[count++] = val;
list.remove(Integer.valueOf(val));
}
}
To shorten the array, use the copy method mentioned above.
intersection = Arrays.copyOf(intersection, count);
System.out.println(Arrays.toString(intersection));
prints
[3, 2, 5, 0, 2]
Note that it does not matter which array is which. If you reverse the arrays for a and b above, the same intersection will result, albeit in a different order.
The first thing I notice is that you are declaring your intersection array at the top of the method.
int[] s = new int[nbr];
You are declaring the same amount of space for the array regardless of the amount you actually use.
Method Arrays.toString(int []) will print any uninitialized slots in the array as "0"
There are several different approaches you can take here:
You can delay initializing the array until you have determined the size of the set you are dealing with.
You can transfer your content into another well sized array after figuring out your result set.
You could forego using Array.toString, and build the string up yourself.

Java while loop mysterious iteration

Can somebody teach me how the while loop in find method is working? Does that somehow iterates the parent array from 0 to the endpoint automatically? until paren[i] != i?
static int find(int i)
{
while (parent[i] != i)
i = parent[i];
return i;
}
// Finds MST using Kruskal's algorithm
static void kruskalMST(int cost[][])
{
int mincost = 0; // Cost of min MST.
// Initialize sets of disjoint sets.
for (int i = 0; i < V; i++)
parent[i] = i;
// Include minimum weight edges one by one
int edge_count = 0;
while (edge_count < V - 1)
{
int min = INF, a = -1, b = -1;
for (int i = 0; i < V; i++)
{
for (int j = 0; j < V; j++)
{
if (find(i) != find(j) && cost[i][j] != 0 && cost[i][j] < min)
{
min = cost[i][j];
a = i;
b = j;
}
}
}
It's difficult to see what you're not grasping - it executes as written.
find is called with some value of i
Does the i'th entry in the parent array contain the value i? Yes, then control proceeds to the return statement and we're done.
Otherwise, set the value in i to the value from the i'th entry of the 'parent' array.
Does the i'th entry in the parent array contain the value i?
Yes, then control proceeds to the return statement and we're done.
Otherwise, set the value in i to the value from the i'th entry of the 'parent' array.
… and keep doing this ...
The overall logic seems to be that each entry in the parent array is supposed to identify its parent entry, except that the topmost entry has itself for its parent.
However, since all entries in parent are initialized such that the i'th entry contains i, and nothing changes that, it seems the code shown is incomplete.

Java Accessing the value in array

i don't understand what is the way to access the data in the array and use it as a condition the condition is to stop looping after the content exceeds 4,000,000 and also store and add the value if its value is an even number!
int[] a=new int[40];
int add=0;
a[0]=1;
a[1]=2;
int i=2;
do{
a[i]=a[i-1]+a[i-2];
System.out.println(a[i]);
if(a[i]%2==0)
{
add=add+a[i];
}
i++;
}
while(i<32);
System.out.println(add);
Just put a check for your variable add to see if its value is greater than 4,000,000 and break out of the loop. Do something like this:
if(add > 4000000) {
break;
}
So your final code will look like this:
int[] a=new int[40];
int add=0;
a[0]=1;
a[1]=2;
int i=2;
do{
a[i]=a[i-1]+a[i-2];
System.out.println(a[i]);
if(a[i]%2==0){add=add+a[i];}
if(add > 4000000) {
break; //this will get you out of your loop
}
i++;
}while(i<32);
System.out.println(add);
I would just throw this out there: Using a do-while loop may be making this harder than it has to be. The first part of your code is totally reasonable, but the while i > 32 is less than clear.
I'd look at it this way. After you initialize your array and its first two values with
int[] a = new int[40];
a[0] = 1;
a[1] = 2;
You know that you've accounted for one even value (2). So just initialized add to 2.
Now for the loop. You want to start at i = 2, and iterate as long as add is less than or greater than 4,000,000, right? So make a for loop to express it:
for (int i = 2; add <= 4000000; i++) {
a[i] = a[i - 2] + a[i -1];
if (a[i] % 2 == 0) {
add += a[i];
}
}
No need for the i < 32, and no need for any break statements!
As a matter of interest, this is a good application for Java 8 streams.
class Fib implements IntSupplier {
private int current = 1;
private int previous = 0;
public int getAsInt() {
int next = current + previous;
previous = current;
current = next;
return current;
}
IntStream.generate(new Fib())
.limit(4000000)
.filter(n - > n % 2 == 0)
.sum();

Error when testing for the max value of a table?

I have an error when I try to run a loop that will test the max value of a table.
The table is tabl with a length of c.
int a=0;
int b=0;
while (a<=c) {
int d = tabl[a];
int e = tabl[a+1];
if(d < e)
b = e;
else
b = d;
a++;
}
It's pretty easy, it starts with comparing tabl[0] and tabl[1], and saves the bigger one, and then keeps going until a = c which is the length of the table and then finishes the loop saving the biggest value of the table in b.
But when I run this I get an java.lang.ArrayIndexOutOfBoundsException error code, can anyone help please? thanks!
When you reach a = c - 1 in your loop, your code is looking for the value of tabl[c-1]and tabl[c]. However, since your table is of length c, this causes an java.lang.ArrayIndexOutOfBoundsException. Beware that in Java, arrays are 0-indexed, that is to say, the first element is at index 0 and the last at index (length - 1).
You could write something like that, using a for-each construct :
int max = 0;
for (int element : tabl) {
if (element > max) {
max = element;
}
}
or a simple for loop
int max = 0;
for (int i = 0; i < tabl.length; i++) {
int element = tabl[i];
if (element > max) {
max = element;
}
}
The problem is you are going one past the end of the array. Arrays are zero indexed, so the item at c is going to be IndexOutOfBounds.
Also because you are accessing a + 1, this means that on the loop when a = c - 2, a + 1 will access the last element of the array.
Try:
int a=0;
int b=0;
while (a < c - 1){
int d = tabl[a];
int e = tabl[a+1];
if(d<e) { b=e;} else { b=d; }
a++;
}
NB: The change is to say a < c - 1 rather than a <= c to ensure that a is never = c when indexing into the array.
You're going out of the bounds of your array when trying to reach tabl[a+1] when a equals c
Your whole algorithm doesn't really make sense: you don't have to compare the current index's value to the next one to find out the max of the array, but rather the current value to the previous maximum value you found out.
A common way to find the maximum value of an array is that one:
int max = table[0];
for(int i = 1; i < c; i++)
if(table[i] > max)
max = table[i];
This way, max will contain the highest value of the array (though the code will throw an Exception if the table is empty).
Please, indent your code better, and use more meaningful variable names (people understand max better than b)

Variable may not have been initizialized (java)

So I was trying to write a function for a ragged array; I may have got this entirely wrong, if so please explain why/how I went wrong. It took me ages to get this far and I have a feeling I've alreayd done it wrong.
I tried compiling it because I'm pretty sure currently it will work, however i'm getting the error "variable n may not have been initialized". My code so far is:
static double[][] exampleMatrix()
{
int n;
double[][] a = new double [3][];
a[0] = new double[n-1];
a[1] = new double[n];
a[2] = new double[n-1];
{
for (int i = 0; i < n-1; i++)
{
a[0][i] = 1;
a[2][i] = 1;
}
for (int i = 0; i < n; i++)
{
a[1][i] = - i - 1;
}
return a;
}
}
I'm probably missing something really really obvious, but i'm not sure what it is to initialize n.
EDIT: I have been told to make this work for a value n that is not yet given.. How would I do that? As in, the user is supposed to input the value of n, and be given an array in return.
Basically, my given question is to implement a function exampleMatrix that, given n, produces the array where all values in teh array a[0] is 1, and same for a[2], and then for a[1], be given a range of values from -1 down to -n for a[1][n-1]. This is what I have so far to calculate this, but I am guessing I have gone completely wrong?
You don't set any value to n. How will your program know how big to make the arrays and how many iterations to run in the for loops?
Method variables (unlike fields) cannot rely on the default value (0 in this case). As such n is not anything when it is declared
int n;
You need to state what n is at some point between declaring it and using it, for example.
int n;
n=7;
or
int n=7;
n not known at compile time
You can also pass n as a variable, if n is variable
static double[][] exampleMatrix(int n){
double[][] a = new double [3][];
a[0] = new double[n-1];
a[1] = new double[n];
a[2] = new double[n-1];
{
for (int i = 0; i < n-1; i++)
{
a[0][i] = 1;
a[2][i] = 1;
}
for (int i = 0; i < n; i++)
{
a[1][i] = - i - 1;
}
return a;
}
}
This method would then be used as
double[][] someMatrix= exampleMatrix(5); //<-- 5 is passed into the function and becomes n
Or you can calculate n in whatever way you see fit
Actually the Problem is with local variable
int n;
The scope of local variables is much narrower. Compiler knows when its getting used. Hence, forcing programmer to initialize the variable
You have to initialize it with any default value as int n=0;
I want to complement the above responses.
You have to take care with the static segments, because when a class load its static segments, the class don't assign default value, if you type:
public static int n;
in your class, the value depends on the programmer. this can throw an exception about initialized.

Categories