Initializing int array - java

I didn't understand why I1.array[0]=555 is? I only want to change arr[0]
Intar I1 = new Intar(10);
int [] arr = I1.array;
arr[0]=555;
public class Intar {
int length;
int [] array;
public Intar(int lengt){
length=lengt;
array=new int[lengt];
Random ran =new Random();
for(int i=0; i<length; i++){
array[i]= ran.nextInt(100);
**When I use System.out.println before and after arr[0]=555 **
I1.array [11, 57, 77, 74, 50, 62, 1, 11, 23, 27]
arr [11, 57, 77, 74, 50, 62, 1, 11, 23, 27]
After arr[0]=555
I1.array [555, 57, 77, 74, 50, 62, 1, 11, 23, 27]
arr [555, 57, 77, 74, 50, 62, 1, 11, 23, 27]

int [] arr = I1.array; does not copy the array, it just assigns the reference to the l1.array to arr. You could use Arrays.copyOf(int[], int) to make a copy like
int[] arr = Arrays.copyOf(l1.array, l1.array.length);

Intar I1 = new Intar(10);
Creates an Intar object, using the constructor public Intar(int lengt), this then initilizes the fields of the Intar object to be an array of 10 random numbers, and a length = 10.
When you write
int [] arr = I1.array;
You are telling arr to reference the object stored in I1's field called array (the array of 10 randomly generated numbers). So when you then set arr[0]=555 you are also setting I1.array's 0th element to be 555 as well.
What you have to understand is I1.array hold a reference to the array which is stored in the Intar object. And now arr is referencing the same object as I1.array is referencing.
For example:
public class Foo {
int val;
public Foo(int val){
this.val = val;
}
int getVal(){
return this.val;
}
}
Then we can do this:
public static void main(String[] args) {
Foo a,b;
a = new Foo(5);
b = a;
b.val = 5;
System.out.println(a.getVal());
}
5 will be the output as b now references a, and we changed the value of b thus we changed the value of a.

Related

Return int array with values greater than threshold

I need to add values to an int[] that are greater than a specific threshold. It does not work for me, because it returns wrong values. For example: "Output for values above 78: [85, 93, 81, 79, 81, 93]", but I get [93, 93, 93, 93, 93, 93]. Why is that so? Thank you.
public int[] getValuesAboveThreshold(int threshold) {
// Output for values above 78: [85, 93, 81, 79, 81, 93]
int[] a = new int[] { 58, 78, 61, 72, 93, 81, 79, 78, 75, 81, 93 };
int temp[] = new int[1];
for (int d : a) {
if (d > threshold) {
System.out.println(d);
temp = new int[temp.length + 1];
for (int i = 0; i < temp.length; i++) {
temp[i] = d;
}
}
}
return temp;
}
You can return ArrayList instead of int[]. Try this code example
public static ArrayList<Integer> getValuesAboveThreshold(int threshold) {
// Output for values above 78: [85, 93, 81, 79, 81, 93]
int[] a = new int[] { 58, 78, 61, 72, 93, 81, 79, 78, 75, 81, 93 };
ArrayList<Integer> temp = new ArrayList<>();
for (int d : a) {
if (d > threshold) {
temp.add(d);
}
}
return temp;
}
Since you initialise the temp array, it defaults to the default value of int and when you loop it to add values, it adds 'd' to all indexes. Try ArrayList instead:
int[] a = new int[] { 58, 78, 61, 72, 93, 81, 79, 78, 75, 81, 93 };
ArrayList<Integer> temp = new ArrayList<Integer>();
for (int d : a) {
if (d > 73) {
System.out.println(d);
temp.add(d);
}
}
System.out.println(temp);
An Array is a container of data, that occupies a contiguous block of memory, which is being allocated accordingly to the specified array's size when a new instance of an array is being created.
Arrays can't grow or shrink, you always need to provide array's length while creating a new array (unless you're specifying the contents of the array in curly braces {A,B,C}, which implicitly gives information about required capacity).
In order to generate an array as a result, firstly you need to find out the number of elements that exceed the threshold, and then create an array which would store the result:
public int[] getValuesAboveThreshold(int[] a, int threshold) {
int count = 0;
for (int i : a) if (i > threshold) count++;
int[] res = new int[count];
int pos = 0; // position in the resulting array
for (int i : a) if (i > threshold) res[pos++] = i; // assign the element and move the position forward
return res;
}
The same logic can be implemented using Stream API in a single statement:
public int[] getValuesAboveThreshold(int[] a, int threshold) {
return Arrays.stream(a)
.filter(i -> i > threshold)
.toArray();
}

How can I reorder my array based off the first value?

I'm working on a problem that says "Write a function called splay that reorganizes a list based on the first value. The first value is called the splaymaster. This function will rearrange the list such that all of the values before the splaymaster are less than or equal to the splaymaster and all of the values after it are greater than the splaymaster. The function also returns the index where the splaymaster is located after the list is rearranged. For example, if the list is [8, 15, 4, 48, 26, 45, 18, 29, 2, 1], the function will rearrange it to become [2, 1, 4, 8, 26, 45, 18, 29, 48, 15] and return the value 3. You may not sort the list." The problem that I seem to be having is for the example above it complains that the index is out of bounds which is my first problem. The next is if I use another array such as {90, 8, 15, 4, 48, 26, 45, 18, 29, 2, 1} I get {1, 90, 8, 15, 4, 48, 26, 45, 18, 29, 2} this is my output when it's not correct. What am I doing wrong? and How do I fix it?
public static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static int splay(int[] x) {
int left = 1;
int right = x.length;
int splaymaster = x[0];
while (left < right) {
if (x[left] <= splaymaster) {
left++;
} else {
swap(x, left, right);
}
swap(x, 0, left - 1);
}
return splaymaster;
}
}
int right = x.length;
The index of the last element in an array is x.length - 1, hence the index is out of bounds. Nonetheless, your algorithm seems incorrect. Merely swapping the elements at different locations is not sufficient. If an element is less than the splaymaster then you need to move all the elements up one and insert the smaller element into the array before the splaymaster. I assume there may be other conditions regarding the way to solve the problem but if there are then they are not clear to me from your question, for example it appears that the order of the elements is not important just as long as all elements before the splaymaster are less than or equal to it. I also assume you need to change the array in place, i.e. you are not allowed to use a second array.
Consider the following code:
import java.util.Arrays;
public class SplayTst {
public static int splay(int x[]) {
int index = 0;
int splaymaster = x[0];
for (int i = 1; i < x.length; i++) {
if (x[i] <= splaymaster) {
int temp = x[i];
for (int j = i; --j >= 0;) {
x[j + 1] = x[j];
}
x[0] = temp;
index++;
}
}
return index;
}
public static void main(String[] args) {
int[] test = new int[]{8, 15, 4, 48, 26, 45, 18, 29, 2, 1};
int ndx = splay(test);
System.out.println(Arrays.toString(test));
System.out.println(ndx);
test = new int[]{90, 8, 15, 4, 48, 26, 45, 18, 29, 2, 1};
ndx = splay(test);
System.out.println(Arrays.toString(test));
System.out.println(ndx);
}
}
Running the above code produces the following output:
[1, 2, 4, 8, 15, 48, 26, 45, 18, 29]
3
[1, 2, 29, 18, 45, 26, 48, 4, 15, 8, 90]
10
Alternatively, assuming that you can use any method to solve the problem, consider the following which uses ArrayList and then converts it to an array and then all the array elements are copied to the original array. Note that the single code line for converting ArrayList<Integer> to int[] is taken from the following question:
How to convert an ArrayList containing Integers to primitive int array?
I refer to this line of the below code:
int[] arr = list.stream().mapToInt(i -> i).toArray();
I iterate through the original array. If an element is greater than the splaymaster then it is appended to the ArrayList, otherwise it is inserted as the first element in the ArrayList.
import java.util.ArrayList;
import java.util.Arrays;
public class SplayTst {
public static int splay(int[] x) {
ArrayList<Integer> list = new ArrayList<>();
list.add(x[0]);
int index = 0;
for (int i = 1; i < x.length; i++) {
if (x[i] <= x[0]) {
list.add(0, x[i]);
index++;
}
else {
list.add(x[i]);
}
}
int[] arr = list.stream().mapToInt(i -> i).toArray();
for (int i = 0; i < x.length; i++) {
x[i] = arr[i];
}
return index;
}
public static void main(String[] args) {
int[] test = new int[]{8, 15, 4, 48, 26, 45, 18, 29, 2, 1};
int ndx = splay(test);
System.out.println(Arrays.toString(test));
System.out.println(ndx);
test = new int[]{90, 8, 15, 4, 48, 26, 45, 18, 29, 2, 1};
ndx = splay(test);
System.out.println(Arrays.toString(test));
System.out.println(ndx);
}
}

code for generating none repeating random numbers. Looks fine to me but when i run it gives me the same number

import java.util.Random;
public class Practice_assignment {
public static void main(String[] args){
int[] winning_numbers = {0,0,0,0,0,0,0,0,0,0} ;
//The i++ for the first loop is in the second loop. I was trying to ensure it only goes to
the next value of the loop once a unique value has been gotten.
for (int i=0; i<10;){
int max = 99;
int min = 1;
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
for (int j=0;j<=i;j++){
if (j<i && winning_numbers[j]==randomNum){
break;
}
else if (j==i && i<10){
winning_numbers[i] = randomNum;
System.out.println(winning_numbers[i]+" ");
i++;
}
}
}
}
}
If I understood correctly what you are trying to achieve, I think you could use something like this:
public class RandomNumbers {
public static void main(String[] args) {
int[] winning_numbers = {0,0,0,0,0,0,0,0,0,0} ;
Random random = new Random();
for(int i = 0; i < winning_numbers.length; i++) {
OptionalInt generatedInt = random.ints(1, 0, 100).findFirst(); // generates a stream of 1 number between 0 and 99 and gets the first (and only) one generated
while (contains(winning_numbers, generatedInt)) {
generatedInt = random.ints(1, 0, 100).findFirst(); // while the generated number is already in the array, generate a new one
}
winning_numbers[i] = generatedInt.getAsInt();
}
System.out.println(Arrays.toString(winning_numbers));
}
// this method will check if the given array already contains the generated int
private static boolean contains(int[] arr, OptionalInt generatedInt) {
return Arrays.stream(arr).anyMatch(number -> generatedInt.getAsInt() == number);
}
}
I ran it a couple of times and here are some outputs I generated with this code:
[52, 54, 21, 62, 47, 13, 94, 36, 82, 25]
[35, 37, 16, 81, 22, 71, 17, 94, 56, 8]
[51, 50, 80, 62, 18, 88, 1, 53, 44, 79]
[16, 95, 18, 66, 31, 4, 1, 55, 52, 26]
[4, 11, 65, 68, 22, 76, 95, 67, 35, 92]
[49, 87, 34, 88, 71, 57, 12, 76, 70, 78]
It appears you want to generate an array of winning_numbers. Here is one ways to do it.
create a helper method to look for duplicate numbers and return true if a duplicate is found.
then iterate over the array checking for the current random number and adding it if unique.
note that min, max, and rand should be initialized outside the loop.
Random rand = new Random();
int[] winning_nummbers = new int[10];
int max = 99;
int min = 1;
for (int i = 0; i < 10;) {
int randomNum = rand.nextInt((max - min) + 1) + min;
// if does not contain a duplicate, then assign
if (!contains(winning_numbers, randomNum)) {
winning_numbers[i++] = randomNum;
}
}
System.out.println(Arrays.toString(winning_numbers));
Prints something like this.
[46, 91, 5, 2, 42, 58, 74, 24, 53, 36]
The helper method.
public static boolean contains(int[] array, int v) {
for (int i = 0; i < array.length; i++) {
if (array[i] == v) {
return true;
}
}
return false;
}
If you want to use streams you can do it like so using a Random instance.
stream values form min to max inclusive.
drop duplicates with distinct
limit(10) limits to 10 values.
put them in an array
int[] winning_numbers = rand.ints(min,max+1)
.distinct()
.limit(10)
.toArray();

using a java switch stament to determine what method to call and repeatedly calling that method

I'm writing a java program where the user can select a sorting algorithm from a list and specify the size of an array to be sorted. The program then generates an array of the specified size filled with random integers and uses a switch statement with a case for each sorting algorithm to call the method for the user's chosen algorithm using the generated array as a parameter.
I want to update my code to allow the user to specify how many arrays are to be sorted with their chosen algorithm. I want to use a for loop to randomly generate and sort the arrays however this doesn't seem ideal because I would have to either:
Place the switch block inside the for loop and check it every loop, even though the same sorting algorithm will be used each time.
Place a for loop in each case within the switch block and have a lot of repeated code in the form of for loops.
Is there a better implementation for this than using switch cases and for loops?
Define an interface (perhaps even a functional interface) named Sorter that has a method
int [] sort( final int [] values )
or
var sort( final int [] values )
if you sort the array in-place.
Implement that interface for each sorting algorithm.
Then you can have a variable Sorter sorter in your program that holds the implementation; it will be initialised in your switch/case statement, based on the user selection.
In your for loop, you will call sorter.sort() for each array to sort.
You can even avoid the switch/case statement by creating a Map<String,Sorter> data structure that is initialised with the name of the sort algorithm as the key and instances of the implementation of Sorter as the value. If Sorter is a functional interface, you can just assign a reference to the respective sort() methods to the Map.
However, this is known as the Strategy pattern …
I decided to try throwing together an example of how you could go about this based off of tquadrat's idea of using a functional interface. I hope it helps!
import java.util.ArrayList;
import java.util.Random;
public class Sorting {
#FunctionalInterface
interface SortType {
Integer[] sort(Integer[] array);
}
public static void main(String[] args) {
int numArrays = 5;
int numValues = 10;
ArrayList<Integer[]> unsortedArrays = generateArrays(numArrays, numValues);
System.out.println("Unsorted:");
print(unsortedArrays);
ArrayList<Integer[]> sortedArrays = sortArrays(unsortedArrays, Sorting::bubbleSort);
System.out.println("\nSorted:");
print(sortedArrays);
}
//Put together random values
private static ArrayList<Integer[]> generateArrays(int numArrays, int numValues) {
ArrayList<Integer[]> unsortedArrays = new ArrayList<>();
Random rand = new Random();
for (int i = 0; i < numArrays; i++) {
Integer[] array = new Integer[numValues];
for (int j = 0; j < numValues; j++) {
array[j] = rand.nextInt(100);
}
unsortedArrays.add(array);
}
return unsortedArrays;
}
//Loop through using the given sorting method on each array
private static ArrayList<Integer[]> sortArrays(ArrayList<Integer[]> arrays, SortType sortType) {
ArrayList<Integer[]> sortedArrays = new ArrayList<>();
for (Integer[] array : arrays) {
sortedArrays.add(sortType.sort(array));
}
return sortedArrays;
}
//Example sort to use with parameters and return matching the interface
private static Integer[] bubbleSort(Integer[] array) {
int n = array.length;
for (int i = 0; i < n - 1; i++)
for (int j = 0; j < n - i - 1; j++)
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
return array;
}
//Method to print the results
private static void print(ArrayList<Integer[]> arrays) {
for (Integer[] array : arrays) {
for (Integer i : array)
System.out.print(i + ", ");
System.out.println();
}
}
}
Sample output:
Unsorted:
67, 54, 83, 67, 62, 96, 6, 24, 66, 19,
3, 37, 45, 36, 81, 45, 5, 46, 5, 84,
10, 8, 95, 50, 82, 38, 36, 18, 80, 98,
52, 27, 18, 17, 77, 51, 18, 72, 55, 76,
79, 84, 92, 85, 61, 74, 64, 29, 95, 64,
Sorted:
6, 19, 24, 54, 62, 66, 67, 67, 83, 96,
3, 5, 5, 36, 37, 45, 45, 46, 81, 84,
8, 10, 18, 36, 38, 50, 80, 82, 95, 98,
17, 18, 18, 27, 51, 52, 55, 72, 76, 77,
29, 61, 64, 64, 74, 79, 84, 85, 92, 95,

Copying two arrays into one array

The question is to write a program which takes two arrays of 10 integers each, a and b. c is an array with 20 integers. The program should put array a and b into the array c, the first 10 integers of c from array a, the latter 10 from b. Then the program should display c. This is the code i have so far. It prints the values from arrayA into arrayC but i dont know how to print the values from arrayB into arrayC without overriding the information already in arrayC (arrayB).
public class questionTwo
{
public static void main(String[] args)
{
int [] arrayA = {31, 14, 5, 12, 50, 80, 100, 29, 58, 57};
int [] arrayB = {9, 13, 156, 78, 36, 46, 86, 98, 63, 2};
int [] arrayC = new int [20];
for (int i = 0; i < arrayA.length; i++)
arrayC[i] = arrayA[i];
for (int i = 0; i < arrayB.length; i++)
{
int element = 9;
arrayC[element] = arrayB[i];
element++;
}
System.out.println("The values of ArrayC are: ");
for(int val : arrayC)
{
System.out.println(val);
}
}
}
Before explaining how you might fix your current code, I would first suggest you create arrayC using the lengths of arrayA and arrayB (here that has the same practical result, but it has the advantage that you can add more elements to arrayA or arrayB without modifying the code). Next, in real code, I would use System.arraycopy to perform the copies. And use Arrays.toString(int[]) for printing. Like,
int[] arrayA = { 31, 14, 5, 12, 50, 80, 100, 29, 58, 57 };
int[] arrayB = { 9, 13, 156, 78, 36, 46, 86, 98, 63, 2 };
int[] arrayC = new int[arrayA.length + arrayB.length];
System.arraycopy(arrayA, 0, arrayC, 0, arrayA.length);
System.arraycopy(arrayB, 0, arrayC, arrayA.length, arrayB.length);
System.out.println(Arrays.toString(arrayC));
As for your original code, use arrayA.length and i to get the correct offset. Like,
int[] arrayC = new int[arrayA.length + arrayB.length];
for (int i = 0; i < arrayA.length; i++) {
arrayC[i] = arrayA[i];
}
for (int i = 0; i < arrayB.length; i++) {
arrayC[i + arrayA.length] = arrayB[i];
}
You were really close! Your second loop initializes element to 9 every time, while you should only assign it to 10 once at the beginning:
int element = 10;
for (int i = 0; i < arrayB.length; i++)
{
arrayC[element] = arrayB[i];
element++;
}
Make your function dynamic while you need to add more item into your arrays. I did not test yet, but I hope it work.
public class questionTwo
{
public static void main(String[] args)
{
int [] arrayA = {31, 14, 5, 12, 50, 80, 100, 29, 58, 57};
int [] arrayB = {9, 13, 156, 78, 36, 46, 86, 98, 63, 2};
int [] arrayC = new int [arrayA.length + arrayB.length];
for (int i = 0; i < arrayA.length; i++)
arrayC[i] = arrayA[i];
int element = arrayA.length;
for (int i = 0; i < arrayB.length; i++)
{
arrayC[element+i] = arrayB[i];
}
System.out.println("The values of ArrayC are: ");
for(int val : arrayC)
{
System.out.println(val);
}
}
}
The second loop is wrong. You can use the follow code:
int [] arrayA = {31, 14, 5, 12, 50, 80, 100, 29, 58, 57};
int [] arrayB = {9, 13, 156, 78, 36, 46, 86, 98, 63, 2};
int [] arrayC = new int [20];
System.arraycopy(arrayA, 0, arrayC, 0, arrayA.length);
System.arraycopy(arrayB, 0, arrayC, arrayA.length, arrayB.length);
System.out.println("The values of ArrayC are: ");
for(int val : arrayC) {
System.out.println(val);
}
Your second loop is incorrect because you are setting element to 9 within the loop each time; thus, its value is always reset upon beginning the next iteration. You could move it outside the loop to achieve the result you're looking for. Also, I'd recommend constructing arrayC based on the lengths of arrayA and arrayB, that way you can combine array's of any length.
In addition, I'd also recommend moving the code to combine the arrays to a method to keep things clean and reusable for future endeavors.
public class questionTwo {
private static int[] combineArrays(int[] arrayA, int[] arrayB) {
int[] arrayC = new int[arrayA.length + arrayB.length];
int idx = 0;
for (int x : arrayA) {
arrayC[idx] = x;
idx++;
}
for (int x : arrayB) {
arrayC[idx] = x;
idx++;
}
return arrayC;
}
public static void main(String[] args) {
int[] arrayA = {31, 14, 5, 12, 50, 80, 100, 29, 58, 57};
int[] arrayB = {9, 13, 156, 78, 36, 46, 86, 98, 63, 2};
int[] arrayC = combineArrays(arrayA, arrayB);
System.out.println("The values of ArrayC are: ");
for(int val : arrayC) {
System.out.println(val);
}
}
}
Also, it is often considered a poor practice to use Java's primitive arrays. Check out List and related objects for more flexible and full-featured options.

Categories