How to fix this Java Algorithm? - java

I have looked around Stack Overflow and did some work myself with this code but doesn't matter whatever I do the answer prints to false but it has to print to true, also how can I Plot their running times as a function of their input size as scatter plots and then choose representative values of the size n, and run at least 5 tests for each size value n in the tests?
PrefixAverages1
import java.util.Arrays;
public class PrefixAverages1 {
static double array[] = new double[10];
public static void prefixAverages(){
for (int i = 0; i < 10; i++){
double s = array[i];
for (int j = 0; j < 10; j++){
s = s + array[j];
}
array[i] = s / (i + 1);
System.out.println(Arrays.toString(array));
}
}
public static double[] prefixAverages(double[] inArray) {
double[] outArray = new double[inArray.length];
return outArray;
}
public static void main(String... args) {
System.out.println(
Arrays.equals(
prefixAverages(new double[] {5, 6, 7, 8}),
new double[] {2, 2.5, 3.5, 4}
)
);
}
}
PrefixAverages2
import java.util.Arrays;
public class PrefixAverages2 {
static double array[] = new double[10];
public static void prefixAverages(){
double s = 0;
for (int i = 0; i < 10; i++){
s = s + array[i];
array[i] = s / (i + 1);
}
array[0] = 10;
System.out.println(Arrays.toString(array));
}
public static double[] prefixAverages(double[] inArray) {
double[] outArray = new double[inArray.length];
return outArray;
}
public static void main(String... args) {
System.out.println(
Arrays.equals(
prefixAverages(new double[] {3, 4, 5, 6}),
new double[] {2, 3.5, 4, 5}
)
);
}
}

First you must understand what Arrays.equals() method does. The Arrays.equals() method does comparison operation on two arrays, based on their content; not based on their size. First of all, let's look at your prefixAverages(float [] inArray) method. What you did there is just create a new float array of size equals to the size of the passing array, and then return that newly created array. And in the main method, you are comparing the returning array and a new array that you are supplying. But this is logically not correct. Since the returning array is an empty array; the Arrays.equals() method returns false, as the other array has some values in it. Even if the returning array do have some values, the Arrays.equals() method returns false if both contain different values. Always remember two arrays are equal if and only if they contain same values and the elements should be in the same order. ** Modify your program like this and it'll return **true
import java.util.Arrays;
public class PrefixAverages1 {
static double array[] = new double[10];
public static void prefixAverages(){
for (int i = 0; i < array.length; i++){
double s = array[i];
for (int j = 0; j < array.length; j++){
s = s + array[j];
}
array[i] = s / (i + 1);
System.out.println(Arrays.toString(array));
}
}
public static double[] prefixAverages(double[] inArray) {
double [] outArray = inArray;
return outArray;
}
public static void main(String... args) {
System.out.println(
Arrays.equals(
prefixAverages(new double[] {5, 6, 7, 8}),
new double[] {5, 6, 7,8}
)
);
}
}
One more thing. While using arrays in loop; always use array.length method to do comparison condition checking. Otherwise there is a high change of probability for an ArrayOutOfBoundsException condition.

I'm guessing because it's hard to understand what you are trying to do. But right now I'm not even sure how this code compiles, because you haven't defined any constructors, and you are (apparently attempting to) call a constructor (with the same name of a static class function, confusing AND bad form) with an array parameter. I'm guessing you meant to call the static method that takes a double[] parameter. (Right now, and here's the confusing part, it shouldn't compile because you should have to prefix the class name to call a static function.). Even that would fail, though, because that method returns an empty array of the same length of the input array. To top it all off, the "algorithm" section of your code is never even called.
I'd suggest just stepping through this in a debugger. That way you could see what the code is doing in real time and correct it if it's not what you meant.
Also, if you'd followed normal coding conventions (never name a function after the class; only constructors), it would be easier to spot errors like that.
Edit: I see how it compiles now. Still, naming the function after the class makes me think "constructor", along with everyone else on the planet.

The output you expect is incorrect; for the input 5, 6, 7, 8 the prefix average should be 5.0, 5.5, 6.0, 6.5.
After the first value 5, there has been one value (5). After the second value (6 + 5) there have been two values 11 (and 11 / 2 is 5.5). Then 6 (because 6+5+7 is 18) and 18/3 is 6. Finally 18+8 is 26 and 26/4 is 6.5
static double[] prefixAverages(double[] x) {
int len = x.length;
double[] arr = new double[len];
double sum = 0;
for (int i = 0; i < len; i++) {
sum += x[i];
arr[i] = sum / (i + 1);
}
System.out.println(Arrays.toString(arr));
return arr;
}

Related

Java: Error Trying to Convert Comparable Array to Integer Array

I am currently implementing a generic version of the longest increasing subsequence problem in Java. The method works as intended, but when I try to use Comparable[] instead of Integer[] (or int[]), the program won't compile. The error given is "Comparable cannot be cast to Integer". I understand the error and what it means, but I don't know how to fix it. Any help would be greatly appreciated :)
I have already tried making the method's return type a generic (>), but the problem is that Java does not allow generic array creation. I've tried just using Integer[] as my return type, and while that compiles and works properly, it's not what I want.
public class LIS {
public static void main(String[] args) {
final Integer[] arr = {-1, 2, 4, 2, 33, 4, 7, 8, 10, 7, 5, 4, 5, 5, 1};
final Integer[] LIS = (Integer[]) lis(arr);
for (int i : LIS) {
System.out.print(i + " ");
}
}
public static Comparable[] lis(Comparable[] arr) {
// We use Comparable[] so we can use interchangably with any Comparable type
final int N = arr.length;
// Java conveniently initializes array values to 0:
int[] lisEndingHere = new int[N];
for (int i = 0; i < N; i++) {
lisEndingHere[i] = 1;
int curMax = 0;
for (int j = 0; j <= i; j++) {
if (arr[i].compareTo(arr[j]) <= 0) continue;
if (lisEndingHere[j] > curMax) {
curMax = lisEndingHere[j];
}
}
lisEndingHere[i] += curMax;
}
// Find and return the longest increasing subsequence:
int max = 0;
for (int i = 0; i < N; i++) {
if (lisEndingHere[i] > max) max = lisEndingHere[i];
}
Comparable[] LIS = new Comparable[max];
for (int i = N-1; i >= 0 && max != 0; i--) {
if (lisEndingHere[i] == max) {
LIS[--max] = arr[i];
}
}
return LIS;
}
}
Just change the line
final Integer[] LIS = (Integer[]) lis(arr);
to
final Comparable[] LIS = lis(arr);
and also update the for loop.
Your method returns a Comparable array, so you cant downcast to an Integer array, but since the implementation of your numbers are Integers, they are still treated as such during runtime.
Setting the result to an Integer array is against the purpose of making a generic method anyways. For something to be passed to your method, it must have a compareTo method, and inherently has a toString method, and that satisfies everything you need the program to do.
There is nothing to fix here. Here:
Integer[] LIS = (Integer[]) lis(...)
Your method lis() returns an array of Comparable objects. A Comparable array isn't an Integer array! Thus that cast can't work conceptually.
Yes, that array contains Integer objects, but the array type isn't "array of integer".
You would have to iterate the resulting array, then you can cast the individual entries. But you can't cast the array type itself into something that it isn't!
Beyond that, you could use generics with lists instead.

Reversing elements in Arrays

public static void main(String[] args) {
int[] HwArray = new int[10];
for (int i = 0; i < HwArray.length; i++) {
HwArray[i] = i;
}
int count = 0;
for (int i = 0; i < HwArray.length; i++){
HwArray[i] = (int) (100 + Math.random() * 100);
System.out.print("HwArray[i]=" + HwArray[i]);
}
}
{
int[] reverse(int[] HwArray); {
int[] reversed = new int[HwArray.length];
for (int i=0; i<HwArray.length; i++) {
reversed[i] = HwArray[HwArray.length - 1 - i];
}
return reverse;
}
}
}
Sorry, I'm still learning. I'm trying to reverse the order of all the elements, but I keep receiving an error. Am I doing something wrong?
To be honest, you're actually not that far off. The reverse function actually seems to work okay but you have all kinds of weird syntax errors and you're not even calling the reverse method. Try doing this:
Move the reverse method inside the class where main is defined. If you want to call it directly from main you'll have to make it an static method.
Get rid of the extra curly braces on lines 17 and 25.
Remove the semicolon on line 18 when declaring reverse. It shouldn't be there.
The reverse method is trying to return a variable called reverse. That's the name of the method, you can't do that. I think you meant to return reversed.
Actually call the reverse method after you have initialized the array with random numbers. Then print the array out again to verify that it worked.
Notice that you're not actually printing out the values of the array on line 11. That should be System.out.println("HwArray[" + i + "]=" + HwArray[i]);
I think the conceptually easiest way to reverse the order of elements in an array is to swap each ith element in the first half of the array of size N with the N-ith element in the second half:
int[] reversed = new int[10];
for (int i=0; i < HwArray.length/2; ++i) {
reversed[i] = HwArray[HwArray.length-1-i];
reversed[HwArray.length-1-i] = HwArray[i];
}
Demo here:
IDEOne
There are many errors:
First of all, it should be return reversed instead of return reverse.
Then, you cannot define any method inside a method(here, method reverse is defined inside the main method)
Then, you can do one thing, remove the following two braces:
1: The opening brace just before int[] reverse(int[] HwArray)
2: The closing brace in the last line
Last, it should be int[] reverse(int[] HwArray) { instead of int[] reverse(int[] HwArray); {
Comparator<Integer> comparator = new Comparator<Integer>() {
#Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
};
// option 1
Integer[] array = new Integer[] { 11, 44, 4, 3, 123 };
Arrays.sort(array, comparator);
// option 2
int[] array2 = new int[] {11, 44, 4, 3, 123};
List<Integer>list = Ints.asList(array2);
Collections.sort(list, comparator);
array2 = Ints.toArray(list);
// option 3
List<Integer> integersList = Ints.asList(arr);
Collections.sort(integersList, Collections.reverseOrder());

finding sums in 2 dimentional arrays java

A project I am doing requires me to find horizontal and vertical sums in 2 dimensional arrays. So pretty much its a word search (not using diagonals) but instead of finding words, the program looks for adjacent numbers that add up to int sumToFind. The code below is what I have come up with so far to find horizontal sums, and we are supposed to implement a public static int[][] verticalSums as well. Since I have not yet completed the program I was wondering, first of all, if what I have will work and, secondly, how the array verticalSums will differ from the code below. Thank you
public static int[][] horizontalSums(int[][] a, int sumToFind) {
int i;
int start;
int sum = 0;
int copy;
int [][] b = new int [a[0].length] [a.length];
for (int row = 0; row < a.length; row++) {
for ( start = 0; start < a.length; start++) {
i = start;
sum = i;
do {
i++;
sum = sum + a[row][start];
}
while (sum < sumToFind);
if(sum == sumToFind) {
for (copy = start; copy <= i; copy++) {
b[copy] = a[copy];
}
}
for (i = 0; i < a[0].length; i++) {
if (b[row][i] != a[row][i])
b[row][i] = 0;
}
}
}
return b;
}
Your code won't work.... (and your question is "if what I have will work?" so this is your answer).
You declare the int[][] b array as new int [a[0].length] [a.length] but I think you mean: new int [a.length] [a[0].length] because you base the row variable off a.length, and later use a[row][i].
So, if your array is 'rectangular' rather than square, you will have index-out-of-bounds problems on your b array.
Your comments are non-existent, and that makes your question/code hard to read.
Also, you have the following problems:
you set sum = i where i = start and start is the index in the array, not the array value. So, your sum will never be right because you are summing the index, not the array value.
in the do..while loop you increment i++ but you keep using sum = sum + a[row][start] so you just keep adding the value to itself, not the 'next' value.
At this point it is obvious that your code is horribly broken.
You need to get friendly with someone who can show you how the debugger works, and you can step through your problems in a more contained way.
Test is very simple
public static void main(String[] args) {
int[][] a = {{1, 2}, {1, 0}};
int[][] result = Stos.horizontalSums(a, 1);
System.out.println(Arrays.deepToString(result));
}
Result
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
When you fix this problem, then this should print something like this
[[1, 2], [1, 0]]

Why does this not return the proper array (java)?

I have this method that doubles my initial array and then returns it as the new array. When I then reprint the new array, it doesn't show that it doubled. I will paste just the single method, but if it's not enough, let me know. It will print it correctly in the method when I use the second for loop, but when I call the method to print the array, it prints the initial array.
public static int [] doubleArray(int [] p)
{
int [] newArr = new int [p.length * 2];
for (int i = 0; i < p.length; i++)
{
newArr[i] = p[i];
}
p = newArr; //Here I set the new doubled array to equal the array in parameters
for (int i = 0; i < p.length; i++)
{
System.out.print(p[i] + " ");
}
return p;
}
you're populating newArr only through length of p
When you set p = newArr, the array p is still going to keep its size, so its length will not double. You could try to return newArr instead of p, which should give you the doubled array you're looking for.
You are only iterating to p.length. You need to modify your logic to double the length in your first for loop while retaining the correct index to use.
It does doubles the length. Did you want the values to be copied too?
public static int [] doubleArray(int [] p)
{
int [] newArr = new int [p.length * 2];
for (int i = 0; i < p.length; i++)
{
newArr[i] = p[i];
newArr[2*i] = p[i]; //copy the value
}
p = newArr; //Here I set the new doubled array to equal the array in parameters
for (int i = 0; i < p.length; i++)
{
System.out.print(p[i] + " ");
}
return p;
}
length extended.
try this...
public static void main(String[] args) {
int[] a = {1,2,4};
int[] s = doubleArray(a);
System.out.println(Arrays.toString(s));
}
it gives output [1, 2, 4, 0, 0, 0]
Arrays are objects and passed by reference. So if you expect that variable you passed to this method will change it's reference you are wrong.
I ran this code and its produces array of double length and at the beginning there are values of original array. As you use array of primitive type, empty places are populated with default values(0 for int)
Works fine for me. Are you sure you have the right reference for the returned value?
In any case have a look at System.arraycopy
public static void main (final String args[])
{
int [] p = {1,2,3,4,5,6,7,8,9};
final int [] newArr = new int [p.length * 2];
for (int i = 0; i < p.length; i++)
{
newArr[i] = p[i];
}
p = newArr; //Here I set the new doubled array to equal the array in parameters
for (int i = 0; i < p.length; i++)
{
System.out.print(p[i] + " ");
}
}
Ok, #ZouZou solved the issue. When I called the method, I needed to set the initial array to equal the method. Thus when I returned the p array, it wrote it to the initial array.
ie;
initialArray = doubleArray(initialArray);
This works totally fine for me. I guess you have called the method in main like following:
public static void main (final String args[])
{
int [] p = {1,2,3,4,5,6,7,8,9};
doubleArray(p);
for (int i = 0; i < p.length; i++)
{
System.out.print(p[i] + " ");
}
}
In the doubleArray method, you didn't extend the original array. But instead, you return a new one with extended size. So the changes will not reflect to the original array outside of the method.
To get the new one, you should catch the returned array and do printing with the new one.
Is this your actual question? Please clarify!
If yes: normally you can change the original array and make the changes reflects outside the method by changing the return type to void. Those changes could be changing elements' value. But you can't change an array's size once it is declared.

How can I concatenate multiple rows in a matrix

In Java I would like to concatenate an array (a[], fixed length) to an array of the same length, to create a matrix M[2][length of a]. This way I would like to subsequently paste more of those arrays onto the matrix. (Comparable to the Matlab vertcat function..C=[A;B])
Is this possible?
Thanks
Yes, it is possible. Here is an example:
public class Main
{
public static void main(String[] args)
{
int[] A = new int[]{1, 2, 3};
int[] B = new int[]{4, 5, 6};
int[][] M = new int[2][];
M[0] = A;
M[1] = B;
for ( int i = 0; i < 2; i ++ ){
for (int j = 0; j < M[i].length; j++ ){
System.out.print(" "+ M[i][j]);
}
System.out.println("");
}
}
}
The above prints out:
1 2 3
4 5 6
We can do even better than that, though. If you are using Java 5 or higher, use:
public static int[][] vertcat(int[]... args){
return args;
}
Then you can write:
int[][] M = vertcat(A,B);
And it will work for any number of arguments.
Edit
The above method stuffs the original arrays into another array, which means that any modification to the result will affect the original arrays, which may be undesireable. Use the following to copy the values:
public static int[][] copyMatrix(int[][] original){
if ( (original==null) || (original.length==0) || (original[0].length == 0) ){
throw new IllegalArgumentException("Parameter must be non-null and non-empty");
}
rows = original.length;
cols = original[0].length;
int[][] cpy = new int[rows][cols];
for ( int row = 0; row < rows; row++ ){
System.arraycopy(original[row],0,cpy[row],0,cols);
}
return cpy;
}
If you want vertcat to return a copy rather than the original, you can redefine it as:
public static int[][] vertcat(int[]... args){
return copyMatrix(args);
}
As far as I know, Java has no built-in support for matrices and matrix-related operations. I would either use a 2D array, write my own Matrix wrapper class (in simpler cases) or hunt down a good Matrix library (e.g. http://jmathtools.berlios.de/).

Categories

Resources