Function in java outputs different results when called multiple times - java

I have a function called tournamentTreeKSelection which finds the K-th largest element in an array. The function takes three parameters, the array, the same array again and the value of K. The purpose of sending two copies of the array is so that during recursive calls, I can modify one copy of the array and still keep the original array I sent in during that call. Here is the code:
import java.util.ArrayList;
import java.util.Arrays;
public class TournamentTree {
public static int max(int a, int b) {
return a > b ? a : b;
}
public static int[] toArray(ArrayList<Integer> list) {
int[] arr = new int[list.size()];
for(int i = 0; i < arr.length; ++i)
arr[i] = list.get(i);
return arr;
}
public static ArrayList<Integer> toList(int[] arr) {
ArrayList<Integer> list = new ArrayList<>();
for(int i : arr)
list.add(i);
return list;
}
public static int tournamentKSelection(int[] data, int[] data_copy, int k) {
ArrayList<Integer> winners = new ArrayList<>();
for(int i = 0; i < data.length; i += 2) {
winners.add(max(data[i], data[i + 1]));
}
if(k > 1 && winners.size() == 1) {
for(int i = 0; i < data_copy.length; i++)
if(data_copy[i] == winners.get(0))
data_copy[i] = -1;
return tournamentKSelection(data_copy, data_copy, --k);
}
if(winners.size() % 2 == 1 && winners.size() != 1) winners.add(-1);
if(winners.size() == 1) return winners.get(0);
return tournamentKSelection(toArray(winners), data_copy, k);
}
}
Now I am going to test it :
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] arr = {9, 10, 8, 7, 6, 500, 4, 3, 2, 1};
System.out.println(TournamentTree.tournamentKSelection(arr,arr,1));
System.out.println(TournamentTree.tournamentKSelection(arr,arr,2));
System.out.println(TournamentTree.tournamentKSelection(arr,arr,3));
}
}
This produces the following results:
500 // ok this is the first largest number
10 // ok this is the second largest number
8 // this is the fourth largest number, not the third
Now let me make the call to System.out.println(TournamentTree.tournamentKSelection(arr,arr,3)); alone without the call to k = 1 and k = 2
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] arr = {9, 10, 8, 7, 6, 500, 4, 3, 2, 1};
System.out.println(TournamentTree.tournamentKSelection(arr,arr,3));
}
}
Now this produces the correct result, which is 9. What's going on ? Individually, the result is correct but when I make previous calls to the same function first the subsequent results are wrong.
The only explanation I can think of at the moment is that something in my TournamentTree class is static that shouldn't be.
Any insight ?

I think you should call your function in this way:
System.out.println(TournamentTree.tournamentKSelection(arr.clone(), arr.clone(), 1));
And I recommend also interesting thread about arrays and passing them to function:
Are arrays passed by value or passed by reference in Java?

In the call TournamentTree.tournamentKSelection(arr,arr,3), you are passing in the same array for both args, so even though you are not changing the array through the second argument, you are changing it by the first. Java uses pass by reference, not pass by value. To maintain the original, you have to make a copy and pass in each, like:
public static void main(String[] args) {
int[] arr = {9, 10, 8, 7, 6, 500, 4, 3, 2, 1};
int[] arr_copy = java.util.Arrays.copyOf(arr, arr.length);
System.out.println(TournamentTree.tournamentKSelection(arr,arr_copy,3));
}

Related

Method Paramaters for Method type (int[] nums)

I am working on a code that adds numbers in an array together and makes the sum. However, if a number is 13, that number and the number after it are skipped. I cannot get my main() method to input parameters into the method that I created to do this task however.
The syntax I have currently is:
public static int sum13(int[] nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] ==13 || nums[i]-- == 13) {
continue;
} else {
sum += nums[i];
}
return sum;
}
}
public static void main(String[] args) {
System.out.println(sum13([1, 2, 2, 1]));
System.out.println(sum13([13, 1, 2, 13, 3, 3]));
}
}
On the System.out.println lines, I am getting the error message,
The method sum13(int[]) in the type A3 is not applicable for the arguments (int, int, int, int)
Does anyone know how to resolve this error?
Options:
1 - create an array, since the method is expecting one
sum13(new int[] { 1, 2, 2, 1};
// or
int[] array = { 1, 2, 2, 1}; // short for int[] array = new int[] { 1, 2, 2, 1};
sum13(array);
2 - use varargs parameter (variable arity parameter) like:
public static int sum13(int... nums) { // creates: int[] nums
called with:
sum13(1, 2, 2, 1)
in this case Java will create the array and pass it as int[] nums.
The ... can be used with any type, but it must be the last parameter specified in the method declaration. The compiler will generate the method as if an array is passed - so it is used inside the method as an array of the specified type; the array itself is created when the method is called. Optionally an array can be given instead of the values.
Despite not the (direct) question, be warned that nums[i]-- == 13 is not doing what probably was intended. The Postfix Decrement Expression X--, where X is a variable (or expression denoting one), will decrement the variable and return its value before it was decremented. So nums[i]-- will return the value of nums[i] and decrement the value stored at index i. Probably it was intended to be nums[i-1] == 13, but that will result in an exception when i == 0 (unless not evaluated).
The struct of this question is very good!
The reason for this question is that the parameter of the main method is not applicable for the sum13 method.
About the understood of array is a little wrong. The right solution is
System.out.println(sum13(new int[]{1,2,3,4}));
You can use a simple if-else to skip the number if it is 13 and the number next to it:
public static int sum13(int... nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 13) i++;
else sum += nums[i];
}
return sum;
}
Here, if the number is 13, you just increment i by 1. If the number at the current iteration is 13, it will not add to the sum because the sum is in the else part, also, it will not add the number right next to it, because you increment i by 1, and at the end of the loop i is incremented again which means i will effectively be incremented twice, skipping the number next to 13 if the current number is 13.
Also, I have used variable length arguments as mentioned in the other answers to allow you to pass an arbitrary number of parameters to sum13 and therefore you call it like this:
public static void main(String[] args) {
System.out.println(sum13(1, 2, 2, 1));
System.out.println(sum13(13, 1, 2, 13, 3, 3));
}
Some of the mistakes in your code are-
Return statement inside a for loop.
Wrong declaring and passing the array to the sum13 method.
nums[i]-- == 13 is not the correct way to look back for 'i-1'th element and when looking for the i-1 the element do check it does not goes below zero else you will face ArrayIndexOutOfBounds exception.
public static int sum13(int[] nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 13 || ( i > 0 && nums[i-1] == 13)) {
continue;
}
sum += nums[i];
}
return sum;
}
public static void main(String[] args) {
int[] array1 = {1, 2, 2, 1};
int[] array2 = {13, 1, 2, 13, 3, 3,13,5,13,2,13,1,1,1};
System.out.println(sum13(array1));
System.out.println(sum13(array2));
}
We can create arrays and assingning values like below.
import java.util.*;
class Example{
public static void main(String args[]){
//--------Method 1-----------------
int[] a=new int[5];
int[] b;
b=new int[5];
//int[] x=new int[]; //Illegal -->size
//--------Method 2-----------------
int[] c={10,20,30,40,50};
int[] d;
//d={10,20,30,40,50}; //Illegal
//--------Method 3-----------------
int[] e=new int[]{10,20,30,40,50};
int[] f;
f=new int[]{10,20,30,40,50}; //Legal
int[] g=new int[5]{10,20,30,40,50}; //Ilelgal-->size
}
}
So,In your code(passing array elements as arguments in main methode)should correct like this.System.out.println(sum13(new int[]{1, 2, 2, 1})); System.out.println(sum13(new int[]{13, 1, 2, 13, 3, 3}));
Other thing is nums[i]-- wrong.If we want to get i-1 element we should code as nums[i-1].So, whole code is below.
import java.util.*;
class Demo{
public static int sum13(int[] nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 13 || ( i > 0 && nums[i-1] == 13)) {
continue;
}
sum += nums[i];
}
return sum;
}
public static void main(String[] args) {
System.out.println(sum13(new int[]{1, 2, 2, 1}));
System.out.println(sum13(new int[]{13, 1, 2, 13, 3, 3}));
}
}

Adding a variables in the array into another array

Today, I have a question about the list. I want to put the variables in the array into the another array. For example, if there is a int[] list1 and int[] list2 = {1,2,3,4} and int[] list3 = {5,6,7}, I want to put the variables in list2 and list3 into the list1, making the list1 into {1,2 + 5, 3 + 6, 4 + 7}. Below is the code that I have made:
public int function(int[] parameter) {
int[] intlist;
for (int i = 0; i < intlist.length; i++) {
intlist = addVariable(int[] anotherlist); //the function addVariable(int[] parameter) gets a
//int[] as a paremeter, makes a new int[](which has the same size as the parameter) at the
//inside of the function, add parameter's each and every varibles into the new int[] and
//returns the new int[]. and anotherlist keeps changing in the for statement. This is the
//function that I want to make.
}
return intlist;
}
Next is the code of addVariable:
public static int[] addVariables(int[] intlist) {
int[] intlist2 = new int[intlist.length];
for(int i = 0; i < intlist.length; i++) {
intlist2[i] += intlist[i];
}
return intlist2;
}
So, what I want to do is making the intlist whole, by using for statement and addVariable function. But, the addVariable fuction is not complete, as the two lists can have different size, and the function that I've made didn't consider this. Also, the changes that I've made in the for statement doesn't last, so this is a problem as well. How can I fix this situation? Please help!
This is the code you need
public class Test {
public static void main(String args[]) {
int[] intlist = {1, 2, 3, 4};
int[] anotherlist = {5, 6, 7};
Test.addVariables(intlist, anotherlist);
for (int i : intlist) {
System.out.println(i);
}
}
public static void addVariables(int[] intlist, int[] anotherlist) {
for (int i = intlist.length - 1, j = anotherlist.length - 1; i >= 0 && j >= 0; i--, j--) {
intlist[i] += anotherlist[j];
}
}
}

Java - Recursive Method that takes Cumulative sum in one array and returns another

So here is the problem: create a int [] recursive method that computes cumulative sums in the array numbers, and transform each value in the array by adding to the value the sum of values that precede it in the array. For example, if
numbers = [5, 6, 7, 2, 3, 1],
then
result = [5, (5)+6, (5+6)+7, (5+6+7)+2, (5+6+7+2)+3, (5+6+7+2+3)+1],
i.e.,result = [5, 11, 18, 20, 23, 24].
The caveats are: Cannot use static or void methods, cannot use loops.
Here is my code so far:
public int[] computeCumulativeSums(int[] numbers){
if(numbers.length == 0)
{
return numbers; // Base case
}
else
{
//recursive stage not implemented. Don't know how to implement
return numbers;
}
}
//Helper method
public int [] addNumbers(int [] list, int index)
{
if(index == 0)
{
return list; //Helper method base case
}
else
{
//recursive case
return addNumbers(list, index - 1);
}
}
public boolean searchTable(int[][] data, int element){
return true;
}
public static void main(String [] args){
Recursion r = new Recursion();
int[] numbers = new int[] {5, 6, 7, 2, 3, 1};
System.out.println(Arrays.toString(r.computeCumulativeSums(numbers)));
}
Output: [5, 6, 7, 2, 3, 1]
What I'm asking is a push in the right direction because I'm so lost with this. Your help will be much appreaciated.
What I would recommend is: try to do it with a while loop. The conditions. In the while loop is your stop condition. Now try to convert what is in the while loop into a recursive method (or if you can't, just a method, and then see how the each method could do the following call of the method itself). Does it help you?
State your strategy .. then code the recursive function. You would probably have something like:
function summit(array, i) ...
if i > 0, then set array[i]=array[i-1]+array[i]
if i < array.length the call summit(array,i+1)
return
public static void main(String args [])
{
int [] array = {5,6,7,2,3,1};
array = sum(array,0);
for(int i=0; i<array.length; i++){
System.out.print(" "+array[i]);
}
}
public static int[] sum(int[] array, int index){
if(index==array.length){
return array;
}
if(index!=0){
array[index] += array[index-1];
}
return sum(array,index+1);
}
Output: 5 11 18 20 23 24

Removing duplicates from array without using Util classes

Please read the question before marking it as duplicate
I have written following code to remove duplicates from array without using Util classes but now I am stuck
public class RemoveDups{
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45, };
int temp;
for (int i : a) {
for (int j = 0; j < a.length - 1; j++) {
if (a[j] > a[j + 1]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
a = removeDups(a);
for (int i : a) {
System.out.println(i);
}
}
private static int[] removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
}
}
return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
and now the output is
1
2
3
4
5
6
45
52
0
0
0
0
0
0
0
0
0
0
Here my problem is
My code is not working in case of 0s
I am not able to understand how sorting an array can reduce time of execution
Is there any way to remove elements from array without using Util classes I know one way to remove convert array into list and then remove but for that also we need Util classes is there any way to implement by myself.
Since the numbers you deal with are limited to a small range you can remove duplicates by a simple "counting sort": mark the numbers you have found in a set-like data structure and then go over the data structure. An array of boolean works just fine, for less memory usage you could create a basic bitset or hash table. If n is the number of elements in the array and m is the size of the range, this algorithm will have O(n+m) complexity.
private static int[] removeDups(int[] a, int maxA) {
boolean[] present = new boolean[maxA+1];
int countUnique = 0;
for (int i : a) {
if (!present[i]) {
countUnique++;
present[i] = true;
}
}
int[] result = new int[countUnique];
int j = 0;
for (int i=0; i<present.length; i++) {
if (present[i]) result[j++] = i;
}
return result;
}
I am not able to understand how sorting an array can reduce time of execution
In a sorted array you can detect duplicates in a single scan, taking O(n) time. Since sorting is faster than checking each pair - O(n log n) compared to O(n²) time complexity - it would be faster to sort the array instead of using the naive algorithm.
As you are making the result array of the same length as array a
so even if you put only unique items in it, rest of the blank items will have the duplicate values in them which is 0 for int array.
Sorting will not help you much, as you code is searching the whole array again and again for the duplicates. You need to change your logic for it.
You can put some negative value like -1 for all the array items first in result array and then you can easily create a new result array say finalResult array from it by removing all the negative values from it, It will also help you to remove all the zeroes.
In java , arrays are of fixed length. Once created, their size can't be changed.
So you created an array of size18.
Then after you applied your logic , some elements got deleted. But array size won't change. So even though there are only 8 elements after the duplicate removal, the rest 10 elements will be auto-filled with 0 to keep the size at 18.
Solution ?
Store the new list in another array whose size is 8 ( or whatever, calculate how big the new array should be)
Keep a new variable to point to the end of the last valid element, in this case the index of 52. Mind you the array will still have the 0 values, you just won't use them.
I am not able to understand how sorting an array can reduce time of execution
What ? You sort an array if you need it to be sorted. Nothing else. Some algorithm may require the array to be sorted or may work better if the array is sorted. Depends on where you are using the array. In your case, the sorting will not help.
As for your final question , you can definitely implement your own duplicate removal by searching if an element exists more than once and then deleting all the duplicates.
My code is not working in case of 0
There were no zeroes to begin with in your array. But because its an int[], after the duplicates are removed the remaining of the indexes are filled with 0. That's why you can see a lot of zeroes in your array. To get rid of those 0s, you need to create another array with a lesser size(size should be equal to the no. of unique numbers you've in your array, excluding 0).
If you can sort your array(I see that its already sorted), then you could either bring all the zeroes to the front or push them to the last. Based on that, you can iterate the array and get the index from where the actual values start in the array. And, then you could use Arrays.copyOfRange(array, from, to) to create a copy of the array only with the required elements.
try this
package naveed.workingfiles;
public class RemoveDups {
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45, };
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i=0;i<count;i++) {
System.out.println(result[i]);
}
// return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
public class RemoveDups {
public static void main(String[] args) {
int[] a = { 1, 2, 0, 3, 1,0, 3, 6, 2};
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
boolean zeroExist = false;
for (int i : a) {
if(i==0 && !zeroExist){
result[j++] = i;
zeroExist = true;
count++;
}
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i=0;i<count;i++) {
System.out.println(result[i]);
}
// return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
// It works even Array contains 'Zero'
class Lab2 {
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45 };
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i = 0; i < count; i++) {
System.out.println(result[i]);
}
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}

Modifying Array Size Via Static Method

I am trying to resize an array by adding the array size by 1 per method invoke.
I have created a static method and it takes array as its argument.
public static void addArray(int arrayName[]) {
int tempNum[] = new int[arrayName.length]; // save the numbers before add array size
for (int i = 0; i < arrayName.length; i++) { // because by adding/removing array size, it would clear element array
tempNum[i] = arrayName[i];
}
arrayName = new int[arrayName.length + 1]; // adds array size by 1
for (int i = 0; i < arrayName.length - 1; i++) { // sets all the saved numbers to the new element in the array
arrayName[i] = tempNum[i]; // stops at (length - 1) because I want to leave it blank at the last element
}
}
(sorry if the code is messed up, I don't know how to properly post code in here)
In the main, I do this;
public static void main(String[] args) {
int num[] = {0, 1, 2, 3, 4};
addArray(num);
System.out.println(num.length);
}
As you can see, the default array size (length) should be 5, but no matter how many times I invoke the method, it always print as 5.
Now I'm starting to think that static method does not allow the array from main to be resized ?
If it can't, do you have another way to resize an array by specifically using static method only ?
You need to return the array from the function:
public static int[] addArray(int arrayName[]) {
...
arrayName = new int[arrayName.length + 1]; // adds array size by 1
...
return arrayName;
}
public static void main(String[] args) {
int num[] = {0, 1, 2, 3, 4};
num = addArray(num);
System.out.println(num.length);
}
You can simply do this:
int num[] = {0, 1, 2, 3, 4};
num = Arrays.copyOf(num, num.length + 1);
System.out.println(num.length);
This should then print 6.
The issue with your code is that when you call a method, the method receives a copy of the reference. Thus, the method cannot change what object is referenced by the variable in the calling method.
Another approach is to make num a static field::
static int num[] = {0, 1, 2, 3, 4};
public static void main(String[] args) {
addArray(); // or use Arrays.copyOf() as above
System.out.println(num.length);
}
public static void addArray() {
int tempNum[] = new int[num.length + 1];
System.arraycopy(num, 0, tempNum, 0, num.length);
num = tempNum;
}
What you can't do (without complex reflection code) is pass a variable name to the method and have it change the length of an array with that name.

Categories