Error when testing with JUnit using assertArrayEquals - java

When testing this bit of code:
public static int maxRowAbsSum(int[][] array) {
int[][] maxRowValue = {
{3, -1, 4, 0},
{5, 9, -2, 6},
{5, 3, 7, -8}
};
int maxRow = 0;
int indexofMaxRow = 0;
for (int row = 0; row < maxRowValue.length; row++) {
int totalOfRow = 0;
for (int column = 0; column < maxRowValue[row].length; column++){
if (maxRowValue[row][column] > 0) {
totalOfRow += maxRowValue[row][column];
} else {
totalOfRow -= maxRowValue[row][column];
}
}
if (totalOfRow > maxRow) {
maxRow = totalOfRow;
indexofMaxRow = row;
}
}
System.out.println("Row " + indexofMaxRow + " has the sum of " + maxRow);
return indexofMaxRow;
}
using this JUnit code:
#Test
public void maxRowAbsSum() {
int [] i = new int [] {};
assertArrayEquals(i, Exercise2.maxRowAbsSum(numArray));
}
This underlines assertArrayEquals in red saying:
The method assertArrayEquals(int[], int[]) in the type Assert is not applicable for the arguments (int[], int)
Am I writing this the wrong way? How do I test this with JUnit so it has no errors or faliures?

i is an int array while Exercise2.maxRowAbsSum(numArray) returns int.
Comparing them isn't possible and hence the error.

You are trying to compare an array of int (int[]) with a single int returned from maxRowAbsSum() method. That's not going to work, it's comparing apples to oranges and JUnit guards you against this with it's method signatures.
You should write your test to match the maxRowAbsSum() method return type e.g.:
#Test
public void shouldCalculateMaxRowAbsSum() {
int expected = 3; // example value, change to match your test scenario
assertEquals(expected, Exercise2.maxRowAbsSum(numArray));
}

I fixed my code but still used Karol's example:
Instead of return indexOfMaxRow which just returned the index of the row that had the max value, I changed this to return maxRow this returned 23 instead of the 2 that JUnit was expecting.

Related

Boolean assignment not catching, need to understand more

public class MyClass {
public static void main(String args[]) {
int[] nums = {1, 2, 9, 3, 4};
boolean results = false;
int end = nums.length;
if (end>4)end=4;
for (int x=0;x<end;x++)
{
System.out.println(nums[x]);
results = (nums[x] == 9);
}
System.out.println(results);
}
}
The following code checks to see if a 9 is present in the first 4 elements of an array, yet using the boolean operator in this fashion seems to always fail if there are not more than 1 "9" in the first 4 elements of the array.
Why is this? Logically it seems that this should work, and it really helps me to understand better when I understand why something doesn't work.
The reason is that you have itetate all the elements,the result will be the result of the last element,
So you need to stop for when you find the match result
for (int x=0;x<end;x++)
{
System.out.println(nums[x]);
if(nums[x] == 9){
result = true;
break;
}
}
You overwrite results every time. As written, this'll tell you whether the last item in the array equals 9 (which it doesn't), not whether any item in the array equals 9.
You should assign true to result if num[x] == 9; otherwise, don't assign anything.
#lucumt's answer shows an example of how to do that. One other example, just replace
results = (nums[x] == 9);
with
results |= (nums[x] == 9);
where the |= assignment is equivalent to results = results || (num[x] == 9); - in other words, if any value is true, the entire expression will be true. (Note that #lucumt's answer is slightly more efficient because it's O(n) whereas this is Theta(n) - i.e. this will always run exactly n times, where n is the length of the list, but #lucumt's can end the loop early if it finds any 9).
In your for loop you are over writing the value each time. This means you are testing if the 4th value is equal to 9.
you can solve your problem like so:
boolean results = false;
for (int x = 0; x < end; x++) {
System.out.println(nums[x]);
if(nums[x] == 9) {
results = true;
break;
}
}
Try this:
boolean isPresent(int[] nums, int val)
{
for (int x : nums )
{
if (nums[x] == val)
return true;
}
return false;
}
Otherwise you rewrite a value every time you're checking
I wrote you a class. The method nignPresentInFirst4Elements(int[] arr) returns true if the given array contains a 9 in one or more of it's first 4 elements:
public class Test {
private static boolean nignPresentInFirst4Elements(int[] arr) {
if(arr == null)
return false;
for(int i = 0; i < Math.min(arr.length, 4); i++) {
if(arr[i] == 9)
return true;
}
return false;
}
public static void main(String[] args) {
int[][] arrs = new int[][] {
{5, 8, 9, 3},
{5, 8, 9, 3, 8, 26},
{5, 8, 9, 9},
{5, 8, 23, 0}
};
for(int i = 0; i < arrs.length; i++) {
System.out.println(toString(arrs[i]) + " | " + nignPresentInFirst4Elements(arrs[i]));
}
}
private static String toString(int[] arr) {
if(arr == null)
return "null";
String s = "[";
if(arr.length > 0)
s += arr[0];
for(int i = 1; i < arr.length; i++) {
s += ", " + arr[i];
}
s += "]";
return s;
}
}

Returning something other than null [duplicate]

This question already has answers here:
Comparing arrays in JUnit assertions, concise built-in way?
(8 answers)
Closed 4 years ago.
This is probably a really bad way of writing code but heres a program that calculates the total of each row and print it all in brackets.
public static int[] rowsSums(int[][] array) {
int[][] numArray = {
{3, -1, 4, 0},
{5, 9, -2, 6},
{5, 3, 7, -8}
};
int rowTotal = 0;
int row2Total = 0;
int row3Total = 0;
for (int i = 0; i < numArray[0].length; i++) {
rowTotal += numArray[0][i];
row2Total += numArray[1][i];
row3Total += numArray[2][i];
}
System.out.println("(" + rowTotal + "," + row2Total + "," + row3Total + ")");
return null;
}
The output without JUnit is:
(6,18,7)
I am in the process of testing this with JUnit and my code for this:
#Test
public void rowsSums() {
int [] i = new int [] {6, 18, 7};
assertEquals(i, Exercise2.rowsSums(numArray));
}
Yes, I know my output is not supposed to be null because JUnit hates it. What other variable can I return without making JUnit fail or spit an error?
I have to keep these as it is
public static int[] rowsSums(int[][] array) {
int[][] numArray = {
UPDATE: No matter what I try, JUnit always comes up with this error PrntScrn of Error
To return the int[] containing the sums, you'd do
return new int[] { rowTotal, row2Total, row3Total };
That's something you can assert as well then
assertArrayEquals(i, Exercise2.rowsSums(numArray));
Note that it is good practice to separate calculation and output, ie you should move the System.out.println to another function accepting the returned array as a parameter.
If your method is designed to just print a message and not return anything, you should declare its return type to be void.
public static void rowsSums(int[][] array) { ...
Then just remove the return statement.
However, based on your test case, it looks like you want to return an array containing the values that you calculated. Instead of having three internal variables to hold totals (rowTotal, row2Total, and row3Total), those variables could be combined into one array where the totals are stored, then returned.
I think that your method should return the computation performed and not only print a message otherwise you would not have a clear way to test your method.
Besides method names should be verbs/actions and not common names.
So sum() would be clearer.
You could return the sum array of each row in your method and assert the result in your unit test :
public static int[] sum(int[][] array) {
...
return new int[] {rowTotal, row2Total, row3Total};
}
And in your test :
int[] sumExpected = ...
Assert.assertArrayEquals(sumExpected, Exercise2.sum(numArray));
If you will return array as a result you will be able to use it in your jUnit test and compare expected result with actual.
System.out.println("(" + rowTotal + "," + row2Total + "," + row3Total + ")");
int [] result = new int[3];
result[0] = rowTotal;
result[1] = row2Total;
result[2] = row3Total;
return result;
Why do you pass int[][] array to the method, but literally never do anything with it at all?... I'm going to assume you want to use that array structure you passed in order to count each of it's arrays (rows). You also should never mix output with functions. You should return the String, then print it in your main method. As #bill-the-Lizard said, you want to have an array in which holds the row's values and then you would just return an int[] array which contains the rows' counts. You would then have a for loop in your current one which would input the counts into their corresponding array key.
int[][] numArray = {
{3, -1, 4, 0},
{5, 9, -2, 6},
{5, 3, 7, -8}
};
public static int[] rowsSums(int[][] array) {
int[] sum = new int[array.length];
for (int i=0;i<sum.length; i++)
sum[i] = 0;
for (int i = 0; i < sum.length; i++) {
for(int j=0; j< array[i].length; j++)
sum[i] += array[i][j];
}
return sum;
}
int[] result = rowsSums(numArray);

Java how to return an array with fibonacci values starting at 1?

I'm writing a void function fibFill which fills an array with Fibonacci numbers. It doesn't have to return anything.
Here's what I have so far:
void fibFill(int[] fibo) {
fibo[0] = 1;
fibo[1] = 1;
for (int i = 2; i < fibo.length; i++) {
fibo[i] = fibo[i - 1] + fibo[i - 2];
}
int pos(int position) {
return fibo[pos];
}
}
For example, if I pass an array of length 5 to the method, it will override the contents of the passed array like this: [1, 1, 2, 3, 5]
Your fibFill method shouldn't have a pos method embedded in it; and I would make it static (so it can be called without an instance), like
static void fibFill(int[] fibo) {
fibo[0] = 1;
fibo[1] = 1;
for (int i = 2; i < fibo.length; i++) {
fibo[i] = fibo[i - 1] + fibo[i - 2];
}
}
Then you can test it with something like
public static void main(String[] args) {
int[] fib = new int[10];
fibFill(fib);
System.out.println(Arrays.toString(fib));
}
Which outputs (as requested) the fibonacci values starting at 1
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
fixed:
static void fibFill(int [] fibo) {
if(fibo.length==0) return;
if(fibo.length==1)
{
fibo[0]=1;
return;
}
fibo[0] = 1;
fibo[1] = 1;
for (int i = 2;i < fibo.length; i++)
{
fibo[i]=fibo[i-1]+fibo[i-2];
}
}
//there is no need for pos, as you can get it by type fibo[index]
Note that this solution cost you O(n), you can also do it directly by formula and there is also more ways to calculate fibonacci. for more information:
five ways to calculate fibonacci
if (n==0||n==1) {
return n;
}
int smallassumption=fib(n-1);
int smallassumption2=fib(n-2);
int ans=smallassumption+smallassumption2;
return ans;

Function in java outputs different results when called multiple times

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));
}

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;
}
}

Categories