Junit Testing error [closed] - java

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have an assignment on arrays I'm working on and one of the questions is to write a code for a histogram.
The method histogram takes a positive number n indicating the number of divisions in which the span of the data is divided, and returns an array of integers of length n, where each element of the array contains the count of the elements that fall into this
division.
For example, if the data is (0:5; 1:2; 2:4; 9:8; 5:1; 10:5), then its span is
10:0 (from 0:5 to 10:5).
histogram(4) would divide this range into four segments:
0.5—3.0, 3.0—5.5, 5.5—8.0, and 8.0—10.5.
Inspecting the data, we see that 3 values fall in the first segment, 1 value in the second, 0 values in the third, and 2 values in the fourth. Therefore, the returned value is an array of length 4 containing the values (3; 1; 0; 2) in that order.
Note that the sum of the elements in the returned array is equal to the number of
elements in the data array.
here is my code:
#Override
public int[] histogram(int divisions) {
int[] range = new int[divisions];
double segment = span() / divisions;
for (int i = 0; i < data.length; i++) {
if (data[i] <= (smallestElement() + segment)) {
range[0] += 1;
}
if (data[i] <= (smallestElement() + (2 * segment))) {
range[1] += 1;
}
if (data[i] <= (smallestElement() + (3 * segment))) {
range[2] += 1;
}
if (data[i] <= (smallestElement() + (4 * segment))) {
range[3] += 1;
}
}
return range;
}
and here is my Junit test for my method:
#Test
public void testHistogram() {
double[] data = new double[3];
data = new double[]{0.5, 1.2, 2.4, 9.8, 5.1, 10.5};
int[] dat = new int[4];
dat = new int[]{3, 1, 0, 2};
DoubleArrayStatisticalOutcomes x = new DoubleArrayStatisticalOutcomes(data);
assertArrayEquals(dat, x.histogram(4));
}
the test is not passing. can someone tell me what I did wrong ?

You are incrementing all the histogram bins for each value. In your for loop, if a value is less than smallestValue() + segment, all the conditional statements are executed, not just the smallest it matches.
This makes your histogram cumulative. There are four elements total in the first two bins.
Add a continue statement in each if or make if 2-4 into else ifs.
Your function also breaks down the moment you pass a value not equal to 4 as the tests are hardcoded. Try something like (untested):
double lowerBound = smallestElement();
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < divisions; j++) {
if (data[i] <= (lowerBound + (j+1) * segment)) {
range[j] += 1;
continue;
}
}
}

Related

I have a possible logic error while reversing an array [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 months ago.
Improve this question
I've been trying to reverse an array using a for loop while not creating a new temporary array however the array only reverses halfway.
public void reverse() {
int y = 0;
int[] values = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
for (int x = values.length - 1; x >= 0; x--) {
int placeholder = values[x];
values[y] = placeholder;
y++;
System.out.print(values[y] + " ");
}
}
Right now the method returns the values of the array. However, the value is
"1 2 3 4 5 5 4 3 2 1"
The desired output is,
"1 2 3 4 5 6 7 8 9 10".
You're reassigning some of the previously overwritten values back to the array (so you lose half of the values). Instead, you should loop to half the length of the array and swap corresponding elements.
for (int i = 0, j = values.length - 1; i < j; i++, j--) {
int temp = values[i];
values[i] = values[j];
values[j] = temp;
}
System.out.println(java.util.Arrays.toString(values));
Instead of x >= 0, the loop should be terminated as soon as x and y meet or surpass each other, or swapped values would be swapped one more time and back into their original slots.
Also did you forget to assign values[y] to values[x] within the loop body?
public void reverse(int[] values)
{
if (values.length == 0) return;
int x = values.length - 1;
int y = 0;
while (x > y)
{
// swapping
int temp = values[x];
values[x] = values[y];
values[y] = temp;
// moving ptrs
x--;
y++;
}
}
Yes,you are not supposed to directly assign, you should swap, otherwise the value to the left of the equal sign will be overwritten.Another way is to find a variable to record the value on the left side of the equal sign and assign it to the right side.

Printing Odd and Even Elements of an Array [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I'm trying to write a program that reads a sequence of integers and divide it into two sequences. The values on odd positions will be the first sequence and the values of even positions will be the second sequence. The program prints the elements of the first sequence and then the elements of the second sequence separated by a single space. The first input value specifies the number of elements.
Input: 7 1 2 4 5 6 8 9
Expected Output: 1 4 6 9 2 5 8
My Output: 2 0
package twosequences;
import java.util.Scanner;
public class TwoSequences {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] values = new int[n];
for (int i = 0; i < values.length; i ++) {
values[i] = sc.nextInt();
}
int odd = 0;
int even = 0;
int i = 1;
if (i % 2 == 0) {
even = values[i];
} else {
odd = values[i];
}
i++;
System.out.printf("%d %d%n", odd, even);
}
}
I'm not sure why I'm outputting 2 0. Any suggestions?
You need two different loops to iterate over even and odd elements respectively to obtain the desired output.
for (i = 0 ; i < n ; i += 2) {
even = values[i];
System.out.printf("%d ", even);
}
for (i = 1 ; i < n ; i += 2) {
odd = values[i];
System.out.printf("%d ", odd);
}
Hope this helps.
Print the even-numbered elements in one loop; then use another loop to print the odd-numbered elements.
System.out.print(values[0]); // print by itself to avoid prepending " ".
for (int i = 2; i < values.length; i += 2) {
System.out.print(" " + values[i]);
}
for (int i = 1; i < values.length; i += 2) {
System.out.print(" " + values[i]);
}
System.out.println();
you take the second element of an array (2), and only for that one you are checking if it's even or not.
The result goes true for first 'if', and
even = 2;
, the if statement ends and odd stays as declares (0), that' why u got result like that.
If you want output whith more than 2 integers, you need to change
, where n would be all scanned even numbers.
Try to put a counter in first for loop, like
for (int i = 0; i < values.length; i ++) {
values[i] = sc.nextInt();
if(values[i]%2==0) evenCounter++;
}
Now to count odds just count values.length - evenCounter.
Also you do not need to make simple arrays like int[], you can go with
List<Integer> list = new ArrayList<>();
You will be able to add elements in for loop withour knowing how many elements you will be implementing.
Hope some of those helps.

Java Interface Testing and Coding Issues

I have been working on this assignment for the past few hours and I'm stuck on the last method Histogram required for the assignment, I have problems with testing and the code probably (I'm using NetBeans).
the method should do this >
histogram: Takes a positive number n indicating the number of divisions in which
the span of the data is divided, and returns an array of integers of length n, where
each element of the array contains the count of the elements that fall into this
division. For example, if the data is (0.5, 1.2, 2.4, 9.8, 5.1, 10.5), then its span is
10.0 (from 0.5 to 10.5). histogram(4) would divide this range into four segments:
0.5—3.0, 3.0—5.5, 5.5—8.0, and 8.0—10.5. Inspecting the data, we see that 3 values
fall in the first segment, 1 value in the second, 0 values in the third, and 2 values
in the fourth. Therefore, the returned value is an array of length 4 containing the
values (3, 1, 0, 2) in that order.
Note that the sum of the elements in the returned array is equal to the number of
elements in the data array.
here is the code:
#Override
public int[] histogram(int divisions) {
int[] wide = new int[divisions];
double segment = span() / divisions;
for (int i = 0; i < data.length; i++) {
if (data[i] <= (smallestElement() + segment)) {
wide[0] = wide[0]+ 1;
} else if (data[i] <= (smallestElement() + (2 * segment))) {
wide[1] = wide[1]+ 1;
} else if (data[i] <= (smallestElement() + (3 * segment))) {
wide[2] = wide[2]+ 1;
} else if (data[i] <= (smallestElement() + (4 * segment))) {
wide[3] = wide[3]+ 1;
}
}
return wide;
}
and here is the test of the method above:
#Test
public void testHistogram() {
double[] data = new double[3];
data = new double[]{0.5, 1.2, 2.4, 9.8, 5.1, 10.5};
int[] data2 = new int[4];
data2 = new int[]{3, 1, 0, 2};
DoubleArrayStatisticalOutcomes a = new DoubleArrayStatisticalOutcomes(data);
assertArrayEquals(data2, a.histogram(4));
}
I use WebCat to submit my work, and when I submit the assignment it tells me that there's some tests missing for the method plus this "histogram is not accounting for the correct number of elements", my question is does the issue occur in the coding itself or am i missing something, same with the test.
Thanks in advance.
You’re only testing your method with the values from the example. The problem is that you probably wrote the method with this particular example in mind. What will happen if you try to make a histogram with a different length?
You should write more tests with different data and different parameters, and check that they all pass.

in Java, design linear algorithm that finds contiguous subsequence with highest sum

this is the question, and yes it is homework, so I don't necessarily want anyone to "do it" for me; I just need suggestions: Maximum sum: Design a linear algorithm that finds a contiguous subsequence of at most M in a sequence of N long integers that has the highest sum among all such subsequences. Implement your algorithm, and confirm that the order of growth of its running time is linear.
I think that the best way to design this program would be to use nested for loops, but because the algorithm must be linear, I cannot do that. So, I decided to approach the problem by making separate for loops (instead of nested ones).
However, I'm really not sure where to start. The values will range from -99 to 99 (as per the range of my random number generating program).
This is what I have so far (not much):
public class MaxSum {
public static void main(String[] args){
int M = Integer.parseInt(args[0]);
int N = StdIn.readInt();
long[] a = new long[N];
for (int i = 0; i < N; i++) {
a[i] = StdIn.readLong();}}}
if M were a constant, this wouldn't be so difficult. For example, if M==3:
public class MaxSum2 {
public static void main(String[] args){
int N = StdIn.readInt(); //read size for array
long[] a = new long[N]; //create array of size N
for (int i = 0; i < N; i++) { //go through values of array
a[i] = StdIn.readLong();} //read in values and assign them to
//array indices
long p = a[0] + a[1] + a[2]; //start off with first 3 indices
for (int i =0; i<N-4; i++)
{if ((a[i]+a[i+1]+a[1+2])>=p) {p=(a[i]+a[i+1]+a[1+2]);}}
//if sum of values is greater than p, p becomes that sum
for (int i =0; i<N-4; i++) //prints the subsequence that equals p
{if ((a[i]+a[i+1]+a[1+2])==p) {StdOut.println((a[i]+a[i+1]+a[1+2]));}}}}
If I must, I think MaxSum2 will be acceptable for my lab report (sadly, they don't expect much). However, I'd really like to make a general program, one that takes into consideration the possibility that, say, there could be only one positive value for the array, meaning that adding the others to it would only reduce it's value; Or if M were to equal 5, but the highest sum is a subsequence of the length 3, then I would want it to print that smaller subsequence that has the actual maximum sum.
I also think as a novice programmer, this is something I Should learn to do. Oh and although it will probably be acceptable, I don't think I'm supposed to use stacks or queues because we haven't actually covered that in class yet.
Here is my version, adapted from Petar Minchev's code and with an important addition that allows this program to work for an array of numbers with all negative values.
public class MaxSum4 {
public static void main(String[] args)
{Stopwatch banana = new Stopwatch(); //stopwatch object for runtime data.
long sum = 0;
int currentStart = 0;
long bestSum = 0;
int bestStart = 0;
int bestEnd = 0;
int M = Integer.parseInt(args[0]); // read in highest possible length of
//subsequence from command line argument.
int N = StdIn.readInt(); //read in length of array
long[] a = new long[N];
for (int i = 0; i < N; i++) {//read in values from standard input
a[i] = StdIn.readLong();}//and assign those values to array
long negBuff = a[0];
for (int i = 0; i < N; i++) { //go through values of array to find
//largest sum (bestSum)
sum += a[i]; //and updates values. note bestSum, bestStart,
// and bestEnd updated
if (sum > bestSum) { //only when sum>bestSum
bestSum = sum;
bestStart = currentStart;
bestEnd = i; }
if (sum < 0) { //in case sum<0, skip to next iteration, reseting sum=0
sum = 0; //and update currentStart
currentStart = i + 1;
continue; }
if (i - currentStart + 1 == M) { //checks if sequence length becomes equal
//to M.
do { //updates sum and currentStart
sum -= a[currentStart];
currentStart++;
} while ((sum < 0 || a[currentStart] < 0) && (currentStart <= i));
//if sum or a[currentStart]
} //is less than 0 and currentStart<=i,
} //update sum and currentStart again
if(bestSum==0){ //checks to see if bestSum==0, which is the case if
//all values are negative
for (int i=0;i<N;i++){ //goes through values of array
//to find largest value
if (a[i] >= negBuff) {negBuff=a[i];
bestSum=negBuff; bestStart=i; bestEnd=i;}}}
//updates bestSum, bestStart, and bestEnd
StdOut.print("best subsequence is from
a[" + bestStart + "] to a[" + bestEnd + "]: ");
for (int i = bestStart; i<=bestEnd; i++)
{
StdOut.print(a[i]+ " "); //prints sequence
}
StdOut.println();
StdOut.println(banana.elapsedTime());}}//prints elapsed time
also, did this little trace for Petar's code:
trace for a small array
M=2
array: length 5
index value
0 -2
1 2
2 3
3 10
4 1
for the for-loop central to program:
i = 0 sum = 0 + -2 = -2
sum>bestSum? no
sum<0? yes so sum=0, currentStart = 0(i)+1 = 1,
and continue loop with next value of i
i = 1 sum = 0 + 2 = 2
sum>bestSum? yes so bestSum=2 and bestStart=currentStart=1 and bestEnd=1=1
sum<0? no
1(i)-1(currentStart)+1==M? 1-1+1=1 so no
i = 2 sum = 2+3 = 5
sum>bestSum? yes so bestSum=5, bestStart=currentStart=1, and bestEnd=2
sum<0? no
2(i)-1(currentStart)+1=M? 2-1+1=2 so yes:
sum = sum-a[1(curentstart)] =5-2=3. currentStart++=2.
(sum<0 || a[currentStart]<0)? no
i = 3 sum=3+10=13
sum>bestSum? yes so bestSum=13 and bestStart=currentStart=2 and bestEnd=3
sum<0? no
3(i)-2(currentStart)+1=M? 3-2+1=2 so yes:
sum = sum-a[1(curentstart)] =13-3=10. currentStart++=3.
(sum<0 || a[currentStart]<0)? no
i = 4 sum=10+1=11
sum>bestSum? no
sum<0? no
4(i)-3(currentStart)+1==M? yes but changes to sum and currentStart now are
irrelevent as loop terminates
Thanks again! Just wanted to post a final answer and I was slightly proud for catching the all negative thing.
Each element is looked at most twice (one time in the outer loop, and one time in the while loop).
O(2N) = O(N)
Explanation: each element is added to the current sum. When the sum goes below zero, it is reset to zero. When we hit M length sequence, we try to remove elements from the beginning, until the sum is > 0 and there are no negative elements in the beginning of it.
By the way, when all elements are < 0 inside the array, you should take only the largest negative number. This is a special edge case which I haven't written below.
Beware of bugs in the below code - it only illustrates the idea. I haven't run it.
int sum = 0;
int currentStart = 0;
int bestSum = 0;
int bestStart = 0;
int bestEnd = 0;
for (int i = 0; i < N; i++) {
sum += a[i];
if (sum > bestSum) {
bestSum = sum;
bestStart = currentStart;
bestEnd = i;
}
if (sum < 0) {
sum = 0;
currentStart = i + 1;
continue;
}
//Our sequence length has become equal to M
if (i - currentStart + 1 == M) {
do {
sum -= a[currentStart];
currentStart++;
} while ((sum < 0 || a[currentStart] < 0) && (currentStart <= i));
}
}
I think what you are looking for is discussed in detail here
Find the subsequence with largest sum of elements in an array
I have explained 2 different solutions to resolve this problem with O(N) - linear time.

Find Duplicates In Arrays

I am writing a method that would take the values and the array and find duplicates. If there are duplicates, like for instance two values have the same value, I will multiple that value by 2. If two values have the same value, I will multiple that value by 3. This will continue until if seven values are the same. I will multiple that value by 7.
This is my source code.
public static double calculateWinnings(int[]numbers)
{
double total = 0;
for (int i = 0; i < numbers.length - 1; i++)
{
for (int j = i + 1; j < numbers.length; j++)
{
if(numbers[i] == numbers[j])
{
total = numbers[i] * .01;
System.out.println("Total is " + total);
return total;
}
}
}
return total;
}
If order doesn't matter, you should sort first, then analyze.
Sorting will put identical values next to each other, where you could more easily notice them in a for loop.
The Java Collections classes may also be of use here.
See for instance http://download.oracle.com/javase/tutorial/collections/intro/index.html
For instance, if you don't want to sort first and use a loop, you could use a HashMap from the collections classes.
HashMap<Integer, Integer> counts = new HashMap<Integer, Integer>();
for(int i=0; i < numbers.length; ++i){
Integer before = counts.get(numbers[i]);
if (before == null) before=0;
counts.put(numbers[i], before+1);
}
now you have a mapper from numbers to counts
later you can use something like max(counts.valueSet()) to find the maximum count
and then loop back through your hash to see which number caused that.
If you have same values at index 1, 4, 6, you will find them with
i j conclusion
--------------
1 4 2 values
1 6 3 values
4 6 4 values // oops! already counted
and so on. Well you would - but there is no so on, since you return on the first hit:
if(numbers[i] == numbers[j])
{
total = numbers[i] * .01;
System.out.println("Total is " + total);
return total; // oops!
}
Do you mean break?
You should provide some example inputs and outputs. It's not clear exactly what output you expect. Are you just looking to find the most duplicates and then multiply that number by the frequency it appears? For example:
1 2 5 5 5 7 8 8 = three 5's = 15
Or perhaps the two 8's wins because their total is 16? Or are you going to sum all of the duplicates? In any case I'd start with this, where MAX_NUM is the highest number you expect in the array:
int[] counts = new int[MAX_NUM];
for (int i = 0; i < numbers.length; i++) {
counts[numbers[i]]++;
}
Now you have the counts of each number. If you're looking for the number with the highest count:
int num = 0;
int best = 0;
for (int i = 0; i < counts.length; i++) {
if (counts[i] > best) {
num = i;
best = counts[i];
}
}
Now num * best would be 15 for my example. Now num will contain the number that occurs the most and best will be the count for it. If there are two numbers with the same count then the higher number will win. Perhaps though in my example above you want 16 instead of 15 because the two 8's have a greater sum:
int max = 0;
for (int i = 0; i < counts.length; i++) {
max = Math.max(i * counts[i], max);
}
Now max would have 16.

Categories

Resources