how to add two arrays together using a method - java

I am trying to add to lists together. ( I know my class name is not right for it, but whatever)
The problem I am facing is where i have the code:
C[i] = v[i] + x[i];
it says the type of expression must be an array but resolved into a variable.....any suggestions how to get around with it and be able to add two arrays together using a method??
import java.util.Arrays;
public class reverse {
int n;
double [] arr;
public reverse( int input){
n =input;
arr = new double[n];
}
public double[] get_array(){
for (int i = 0; i < n; i ++)
{
arr[i] = i + 1;
}
return arr;
}
public reverse add(reverse v, reverse x){
reverse C = new reverse(3);
for( int i = 0; i < n; i++){
C[i] = v[i] + x[i];
System.out.println(C[i]);
}
return C;
}
public static void main(String[] args){
reverse A = new reverse(5);
reverse B = new reverse(5);
System.out.println( Arrays.toString(A.get_array()));
System.out.println( Arrays.toString(B.get_array()));
}
}

To get the individual arrays from v and x call get_array(). Also, by convention the method get_array() should be getArray() and the class reverse should be Reverse. To correctly size C, get the lengths of v and x and take the max (or the min if you only want elements that appear on both sides). Iterate and add the values, storing the result in C's array. Something like,
public reverse add(reverse v, reverse x) {
reverse C = new reverse(Math.max(v.n, x.n));
double[] vals = C.get_array(), left = v.get_array(), right = x.get_array();
for (int i = 0; i < C.n; i++) {
if (i < left.length && i < right.length) {
vals[i] = left[i] + right[i];
} else if (i < left.length) {
vals[i] = left[i];
} else {
vals[i] = right[i];
}
}
return C;
}
As mentioned, if you only want to add elements present on both sides, then the code can be simplified. Use Math.min to get the correct length and you can eliminate the array length checks. Like,
public reverse add(reverse v, reverse x) {
reverse C = new reverse(Math.min(v.n, x.n));
double[] vals = C.get_array(), left = v.get_array(), right = x.get_array();
for (int i = 0; i < C.n; i++) {
vals[i] = left[i] + right[i];
}
return C;
}

The problem is that by saying reverse C;, you are not creating an array, therefore you cannot use C[i].
public reverse add(reverse v, reverse x){
reverse C = new reverse(3);
for( int i = 0; i < n; i++){
//Replace C with C.arr
C.arr[i] = v[i] + x[i];
System.out.println(C.arr[i]);
}
return C;
}
Here C.arr refers to arr field in C
Also by convention type name should start with a capitalized letter

C,v, and x are Objects of type Reverse, not arrays. You need to access the arrays within the objects.
C.arr[i] = v.arr[i] + x.arr[i];
System.out.println(C.arr[i]);
Also, you don't allow for the fact that they might not be the same size arrays. You might need to allow for that.

Related

Why this Stackoverflow exception is occuring while implementing merge sort in java recursively? [duplicate]

This question already has answers here:
What is a StackOverflowError?
(16 answers)
Closed 3 years ago.
I'm basically trying implement merge sort in Java. For doing so, I've created a class called Array, which has an integer array a[]. The class also has a method called slice(int left, int right) that produces the slice of array and returns the object. Henceforth , there is a sort() method that recursively calls itself and breaks down the array and returns an Array object at the end.
import java.util.*;
class Array
{
int a[];
public Array()
{
a = null;
}
public Array(int x)
{
a = new int[x];
}
public void input()
{
Scanner sc = new Scanner(System.in);
for(int i = 0; i < a.length; i++)
{
System.out.print("Enter a No. = ");
a[i] = sc.nextInt();
}
}
public void display()
{
for(int i = 0; i < a.length; i++)
System.out.print(a[i] + "\t");
System.out.println();
}
public Array slice(int left, int right)
{
Array ob = new Array(left + right + 1);
for(int i = left; i <= right; i++)
ob.a[i] = this.a[i];
return ob;
}
public static Array merge(Array A, Array B)
{
Array C = new Array(A.a.length + B.a.length);
int i, j, k;
i = j = k = 0;
while(i < A.a.length && j < B.a.length)
{
if(A.a[i] < B.a[j])
C.a[k++] = A.a[i++];
else if(A.a[i] > B.a[j])
C.a[k++] = B.a[j++];
else
{
C.a[k++] = A.a[i++]; j++;
}
}
while(i < A.a.length)
C.a[k++] = A.a[i++];
while(j < B.a.length)
C.a[k++] = B.a[j++];
return C;
}
public Array sort()
{
if(this.a.length == 1)
return this;
else
{
return merge(this.slice(0, (this.a.length - 1) / 2).sort(), this.slice(1 + (this.a.length - 1) / 2, this.a.length - 1).sort());
}
}
public static void main()
{
Array x;
Scanner sc = new Scanner(System.in);
System.out.print("Enter the No. of Elements = ");
Array ob = new Array(sc.nextInt());
ob.input();
System.out.println("\n ORIGINAL ARRAY");
ob.display();
System.out.println("\n SORTED ARRAY");
x = ob.sort();
x.display();
}
}
Suppose if I have an object A, which has an integer array a[], then on calling A.sort() must return an object in which all the array elements will be sorted in ascending order.
Error(s) I Got: java.lang.StackOverflowError: null
Firstly, your slice should be implemented like this. I suspect this is the main problem. The way you did it, the slices aren't getting smaller, so the recursion never bottoms out.
public Array slice(int left, int right)
{
int length = right - left; // this is the proper length
Array ob = new Array(length);
for(int i = 0; i < length; i++)
ob.a[i] = this.a[i + left];
return ob;
}
Secondly, merge should be like this.
public static Array merge(Array A, Array B)
{
Array C = new Array(A.a.length + B.a.length);
int i = 0, j = 0, k = 0;
while(i < A.a.length && j < B.a.length)
{
if(A.a[i] < B.a[j])
C.a[k++] = A.a[i++];
else if(A.a[i] > B.a[j])
C.a[k++] = B.a[j++];
else
{
C.a[k++] = A.a[i++];
C.a[k++] = B.a[j++]; // this preserves duplicates
}
}
while(i < A.a.length)
C.a[k++] = A.a[i++];
while(j < B.a.length)
C.a[k++] = B.a[j++];
return C;
}
Then sort becomes
public Array sort()
{
if(a.length < 2)
return this;
int half = a.length / 2;
Array left = slice(0, half).sort();
Array right = slice(half, a.length).sort();
return merge(left, right);
}
The stack is a region of memory of finite size. It's often not that big. When you call a recursive function, each recursive call is placed on the stack. When the recursion finishes, the calls on the stack are popped off and executed.
The problem is if your array is big, and the recursion goes to deep (many calls), you might run out of space on the stack to put the next recursive call. This is a stack overflow.
I made exactly the same mistake at uni once. :)
To fix your program you can:
increase the stack size (this is a hack, there is still a limit to how many recursive calls you can make, it's just higher now)
decrease the memory use of each call (still kind of a hack, probably not very effective either, unless you're storing large data in a local variable)
implement your merge sort iteratively so that you only deal with small pieces of data at a time, instead of putting it all on the stack first, then dealing with it at the end.
Every recursive algorithm can be implemented with iteration (a loop).

Why is insertion sort not working?

Switching from Python to Java and decided to code an insertionsort method. I have written this in Python and tried to switch over the code one-to-one, it all seems good to go but it is not functioning correctly. I cut out all the other class methods/data fields to converse space and tried to limit this code only to that which is relevant to this question:
public class test1 {
static final int NOT_FOUND = -1; // A constant
// Attributes (just one)
private double data[];
// Constructor
test1 (double data[]) {
this.data = data.clone();
}
double getItem (int key) {
return data[key];
}
void insertionSort () {
for (int i = 1;i >= data.length;i++){
double currentElement = data[i];
int k = i - 1;
while(k>=0 & data[k] > currentElement){
data[k+1] = data[k];
k -= 1;
data[k + 1] = currentElement;
}
}
}
public static void main(String[] arg){
double testData[] = {1,4,32,5,673,145,68,14,757};
test1 b = new test1 (testData);
b.insertionSort();
//See how array has changed
for (int i = 0; i < 9; i++) {
System.out.print(b.getItem(i) + ", ");
}
}
}
Change
for (int i = 1; i >= data.length; i++)
to
for (int i = 1; i < data.length; i++)
The reason behind it is that you are retrieving an item from the array data for the index of i. The loop did not work because i was initialized to 1 and the condition i >= data.length was returning false because i is actually smaller than the length of the data array in your example, hence the loop did not run.
There are other troubles with this kind of check in the for loop when retrieving an element from an array because if an index for which you are returning the element is >= than the length of the array you will get an IndexOutOfBoundsException.
I am sure this is not what you meant:
for (int i = 1;i >= data.length;i++){
This will be either an infinite(actually up to overflow) or an empty cycle.
I know that is not exactly what are you asking, but if you are learning Java, maybe you could find useful:
In Java you can use Arrays.sort() :
void insertionSort () {
Arrays.sort(data);
}

Return the index of an arbitrary Object in a 2d array java.

I'm trying to find the index of an object placed in an array. The array has been populated like this
for(i = 0 ; i<n ;i++){
for(j=0; j<n ;j++){
squares[i][j]= new Square(i,j)
}
So the array is basically full of Square objects with no name. I want to make a method that returns the index of a square object, like:
getObject(Square s){
{
I've seen other answers calling for the use of
Arrays.asList(array)
And stuff like that, but they all try to return the index for an int or a String.
How should i go about returning the index for any object?
As long as the comparison operator (equals() method) of your Square is suitable for you, then any of these method would work :
Converting to ArrayList and unsing indexOf and get
Using java.util.Arrays.binarySearch
Do a foreach loop and search manually
etc.
You only need a valid comparison operator, if the default Object.equals()(comparison of object instances) is suitable for your need, then you don't have much to do :
Point getObject(Square s){
{
for(int i = 0; i<n; i++){
for(int j = 0; j<n; j++){
if( squares[i][j].equals(s) ) {
return Point(i, j);
}
}
}
return null;
}
Note that if your array is large, it's not the fastest way to do it.
if you can use equals method (assuming n is defined also, or you can use length) :
public int[] getObject(Square s){
int[] returnIndex = new int[2];
for(int i = 0 ; i<this.n ;i++){
for(int j=0; j<this.n ;j++){
if(s.equals(this.squares[i][j])) {
returnIndex[0] = i;
returnIndex[1] = j;
return returnIndex;
}
}
}
return null;
}
i have solved like this
private ArrayList<Square> squareList= new ArrayList<Square>(9);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
mSquare[i][j] = new Square(i, j);
squareList.add(mSquare[i][j]);
}
}
public int index(int r, int c) {
return squareList.indexOf(Square(r, c));
}

Sort an Integer Array and Store result with its index in Java

hello guys i need to sort some elements of integer in an integer array and need to store the index of the sorted list
assume if the elements in array are
x[]= {10,20,40,70,80,50,30};
i need to get the index of the sorted order say in this case i need to get 4,3,5,2,6,0 (ascending) (array x starting from 0)
A simple way (not algorithmically clever) would be to make a new list (or array) of objects from the existing list that contains the value and the index:
class ValueAndIndex implements Comparable<ValueAndIndex> {
final int value;
final int index;
ValueAndIndex(int value, int index) {
this.value = value;
this.index = index;
}
#Override public int compareTo(ValueAndIndex other) {
// compare on value;
if (this.value < other.value) {
return -1;
} else if (this.value > other.value) {
return 1;
} else {
return 0;
}
}
}
Now, create instances of this class in a list:
List<ValueAndIndex> secondaryList = new ArrayList<ValueAndIndex>(x.length);
for (int i = 0; i < x.length; ++i) {
secondaryList.add(new ValueAndIndex(x[i], i));
}
Sort this list:
Collections.sort(secondaryList);
Now, the indices are still in this list:
int [] indexesInSortedOrder = new int[x.length];
for (int i = 0; i < secondaryList.size(); ++i) {
indexesInSortedOrder[i] = secondaryList.get(i).index;
}
System.out.println(Arrays.toString(indexesInSortedOrder));
Possible solution
//sort the array intio a new array
y[] = x;
Arrays.sort(y); //sort ascending
//final array of indexes
int index_array[] = new int[7];
//iteretate on x arrat
for(int i=0; i<7; i++)
//search the position of a value of the original x array into the sorted y array, store the position in the index array
index_array[i] = arrays.binarySearch(x,y[i]);
you can create an array
y[] = {0,1,2,3,4,5,6};
And ith any sorting algorithm, when you switching moving two elements in array x, do the same in array y
One way to do (what I understand) you need:
Determine the size n of the original array.
Create result array R and initialize its elements with 0 . . n-1
Finally implement one sort algorithm in the way that it sorts a copy(!) of your original array whilst also switching the elements in R
Example run:
Copied Result
Array
------------------
1. 2-3-1 0-1-2
2. 2-1-3 0-2-1
3. 1-2-3 2-0-1
public Map sortDecendingDFSGlobal() {
Map<String, Object> multiValues = new HashMap<String, Object>();
double[] dfs = this.global_dfs;
int[] index = new int[dfs.length];
for (int i = 0; i < dfs.length; i++) {
index[i] = i;//for required indexing
}
for (int i = 0; i < dfs.length; i++) {
//sorting dfsglobal in decending order
double temp = dfs[i];
double swap = dfs[i];
int swapIndex = i;
//keeping track of changing indexing during sorting of dfsglobal
int indStart = index[i];
int indSwap = index[i];
int number = i;
for (int j = i; j < dfs.length; j++) {
if (temp < dfs[j]) {
temp = dfs[j];
swapIndex = j;
indSwap = index[j];
number = j;
}
}
dfs[i] = temp;
dfs[swapIndex] = swap;
index[i] = indSwap;
index[number] = indStart;
}
//again sorting the index matrix for exact indexing
for (int i = 0; i < index.length - 1; i++) {
for(int j = i; j < index.length - 1; j++ )
{
if(dfs[j] == dfs[j + 1] && index[j] > index[j + 1])
{
int temp = index[j];
index[j] = index[j+1];
index[j + 1] = temp;
}
}
}
this.sortedDFS = dfs;
this.arrIndex = index;
multiValues.put("sorted", dfs);
multiValues.put("index", index);
return multiValues;
} //SortedDecendingDFSGlobal()

"ArrayIndexOutOfBoundsException" error when trying to add two int arrays

I'm trying to make an implementation of 'adding' the elements of two arrays in Java.
I have two arrays which contain integers and i wanna add them. I dont want to use immutable variables. I prefer do sth like that : a.plus(b);
The problem is when i add 2 arrays with different length.It tries to add the elements of b to a, but if b has a bigger length it flags an error "ArrayIndexOutOfBoundsException".
I can understand why that's happening. But how can i solve this?
How can i expand array a? :/
public void plus(int[] b)
{
int maxlength = Math.max( this.length, b.length );
if (maxlength==a.length)
{
for (int i = 0; i <= maxlength; i++)
{
a[i] = a[i] + b[i]; //ArrayIndexOutOfBoundsException error
}
}
}
i <= maxlength replace this with i < maxlength.
Your array index is starting at zero, not at one.
So the length of the array is one less than the end index of the array.
When you use <= you are trying to go one element after the last element in your array, Hence the exception.
Also you got to check the length of array b. If length of array b is smaller than a, you will end up facing the same exception.
int maxlength = Math.min( this.length, b.length ); is more appropriate.
Or incase if you don't want to miss out any elements in either of the arrays while adding, ArrayList is the answer for you. ArrayList is the self expanding array you are looking for.
Here is how you can do that -
// First ArrayList
ArrayList<Integer> a = new ArrayList<Integer>();
a.add(1);
a.add(2);
a.add(3);
// Second ArrayList
ArrayList<Integer> b = new ArrayList<Integer>();
b.add(1);
b.add(2);
b.add(3);
b.add(4);
int maxlength = Math.max(a.size(), b.size());
// Add the elements and put them in the first ArrayList in the corresponding
// position
for (int i = 0; i < maxlength; i++) {
if (i < a.size()) {
if (i < b.size()) {
int j = a.get(i);
a.set(i, j + b.get(i));
}
} else {
a.add(i, b.get(i));
}
}
for (int j : a) {
System.out.println(j);
}
How can i expand array a?
Don't use arrays if you need variable-size data structures. Use Lists.
How about this:
private int[] a;
/**
* Adds the specified array to our array, element by element, i.e.
* for index i, a[i] = a[i] + b[i]. If the incoming array is
* longer, we pad our array with 0's to match the length of b[].
* If our array is longer, then only the first [b.length] values
* of our array have b[] values added to them (which is the same
* as if b[] were padded with 0's to match the length of a[].
*
* #param b the array to add, may not be null
*/
public void plus(final int[] b)
{
assert b != null;
if (a.length < b.length) {
// Expand a to match b
// Have to move a to a larger array, no way to increase its
// length "dynamically", i.e. in place.
final int[] newA = new int[b.length];
System.arraycopy(a, 0, newA, 0, a.length);
// remaining new elements of newA default to 0
a = newA;
}
for (int i = 0; i < b.length; i++)
{
a[i] = a[i] + b[i];
}
}
Another version:
private ArrayList<Integer> aList;
public void plusList(final int[] b)
{
assert b != null;
if (aList.size() < b.length) {
aList.ensureCapacity(b.length);
}
for (int i = 0; i < b.length; i++)
{
if (i < aList.size()) {
aList.set(i, aList.get(i) + b[i]);
} else {
aList.add(b[i]);
}
}
}
Edit: Here's the full class with sample run from data in comments
public class AddableArray {
private int[] a;
public AddableArray(final int... a) {
this.a = a;
}
/**
* Adds the specified array to our array, element by element, i.e.
* for index i, a[i] = a[i] + b[i]. If the incoming array is
* longer, we pad our array with 0's to match the length of b[].
* If our array is longer, then only the first [b.length] values
* of our array have b[] values added to them (which is the same
* as if b[] were padded with 0's to match the length of a[].
*
* #param b the array to add, may not be null
*/
public void plus(final int[] b)
{
assert b != null;
if (a.length < b.length) {
// Expand a to match b
// Have to move a to a larger array, no way to increase its
// length "dynamically", i.e. in place.
final int[] newA = new int[b.length];
System.arraycopy(a, 0, newA, 0, a.length);
// remaining new elements of newA default to 0
a = newA;
}
for (int i = 0; i < b.length; i++)
{
a[i] = a[i] + b[i];
}
}
int[] get() {
return a;
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("a[] = [ ");
for (int i = 0; i < a.length; i++) {
if (i > 0) sb.append(", ");
sb.append(a[i]);
}
sb.append(" ]");
return sb.toString();
}
public static void main (final String[] args) {
final AddableArray myAddableArray = new AddableArray(1,2,3);
System.out.println("Elements before plus(): ");
System.out.println(myAddableArray.toString());
final int b[]={1,2,3,4};
myAddableArray.plus(b);
System.out.println("Elements after plus(): ");
System.out.println(myAddableArray.toString());
}
}
Sample run:
Elements before plus():
a[] = [ 1, 2, 3 ]
Elements after plus():
a[] = [ 2, 4, 6, 4 ]
maxlength is the max between the size of a[] and b[], so in a loop from 0 to maxlength, you will get an ArrayIndexOutOfBoundsException when i exceeds the min of the size of a[] and b[].
Try this:
public void plus(int[] b)
{
Polynomial a = this;
int[] c;
int maxlength;
if (a.length>b.length) {
c=a;
maxlength=a.length;
} else {
c=b;
maxlength=b.length;
}
int ca, cb;
for (int i = 0; i < maxlength; i++)
{
if (i<this.length)
ca=a[i];
else
ca=0;
if (i<b.length)
cb=b[i];
else
cb=0;
c[i] = ca + cb;
}
}
Try replacing:
for (int i = 0; i <= maxlength; i++)
with:
for (int i = 0; i < maxlength; i++)

Categories