"ArrayIndexOutOfBoundsException" error when trying to add two int arrays - java

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++)

Related

How to shift element an int left in an array then adding a number to the end? [duplicate]

I have an array of objects in Java, and I am trying to pull one element to the top and shift the rest down by one.
Assume I have an array of size 10, and I am trying to pull the fifth element. The fifth element goes into position 0 and all elements from 0 to 5 will be shifted down by one.
This algorithm does not properly shift the elements:
Object temp = pool[position];
for (int i = 0; i < position; i++) {
array[i+1] = array[i];
}
array[0] = temp;
How do I do it correctly?
Logically it does not work and you should reverse your loop:
for (int i = position-1; i >= 0; i--) {
array[i+1] = array[i];
}
Alternatively you can use
System.arraycopy(array, 0, array, 1, position);
Assuming your array is {10,20,30,40,50,60,70,80,90,100}
What your loop does is:
Iteration 1: array[1] = array[0]; {10,10,30,40,50,60,70,80,90,100}
Iteration 2: array[2] = array[1]; {10,10,10,40,50,60,70,80,90,100}
What you should be doing is
Object temp = pool[position];
for (int i = (position - 1); i >= 0; i--) {
array[i+1] = array[i];
}
array[0] = temp;
You can just use Collections.rotate(List<?> list, int distance)
Use Arrays.asList(array) to convert to List
more info at: https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#rotate(java.util.List,%20int)
Instead of shifting by one position you can make this function more general using module like this.
int[] original = { 1, 2, 3, 4, 5, 6 };
int[] reordered = new int[original.length];
int shift = 1;
for(int i=0; i<original.length;i++)
reordered[i] = original[(shift+i)%original.length];
Just for completeness: Stream solution since Java 8.
final String[] shiftedArray = Arrays.stream(array)
.skip(1)
.toArray(String[]::new);
I think I sticked with the System.arraycopy() in your situtation. But the best long-term solution might be to convert everything to Immutable Collections (Guava, Vavr), as long as those collections are short-lived.
Manipulating arrays in this way is error prone, as you've discovered. A better option may be to use a LinkedList in your situation. With a linked list, and all Java collections, array management is handled internally so you don't have to worry about moving elements around. With a LinkedList you just call remove and then addLast and the you're done.
Try this:
Object temp = pool[position];
for (int i = position-1; i >= 0; i--) {
array[i+1] = array[i];
}
array[0] = temp;
Look here to see it working: http://www.ideone.com/5JfAg
Using array Copy
Generic solution for k times shift k=1 or k=3 etc
public void rotate(int[] nums, int k) {
// Step 1
// k > array length then we dont need to shift k times because when we shift
// array length times then the array will go back to intial position.
// so we can just do only k%array length times.
// change k = k% array.length;
if (k > nums.length) {
k = k % nums.length;
}
// Step 2;
// initialize temporary array with same length of input array.
// copy items from input array starting from array length -k as source till
// array end and place in new array starting from index 0;
int[] tempArray = new int[nums.length];
System.arraycopy(nums, nums.length - k, tempArray, 0, k);
// step3:
// loop and copy all the remaining elements till array length -k index and copy
// in result array starting from position k
for (int i = 0; i < nums.length - k; i++) {
tempArray[k + i] = nums[i];
}
// step 4 copy temp array to input array since our goal is to change input
// array.
System.arraycopy(tempArray, 0, nums, 0, tempArray.length);
}
code
public void rotate(int[] nums, int k) {
if (k > nums.length) {
k = k % nums.length;
}
int[] tempArray = new int[nums.length];
System.arraycopy(nums, nums.length - k, tempArray, 0, k);
for (int i = 0; i < nums.length - k; i++) {
tempArray[k + i] = nums[i];
}
System.arraycopy(tempArray, 0, nums, 0, tempArray.length);
}
In the first iteration of your loop, you overwrite the value in array[1]. You should go through the indicies in the reverse order.
static void pushZerosToEnd(int arr[])
{ int n = arr.length;
int count = 0; // Count of non-zero elements
// Traverse the array. If element encountered is non-zero, then
// replace the element at index 'count' with this element
for (int i = 0; i < n; i++){
if (arr[i] != 0)`enter code here`
// arr[count++] = arr[i]; // here count is incremented
swapNumbers(arr,count++,i);
}
for (int j = 0; j < n; j++){
System.out.print(arr[j]+",");
}
}
public static void swapNumbers(int [] arr, int pos1, int pos2){
int temp = arr[pos2];
arr[pos2] = arr[pos1];
arr[pos1] = temp;
}
Another variation if you have the array data as a Java-List
listOfStuff.add(
0,
listOfStuff.remove(listOfStuff.size() - 1) );
Just sharing another option I ran across for this, but I think the answer from #Murat Mustafin is the way to go with a list
public class Test1 {
public static void main(String[] args) {
int[] x = { 1, 2, 3, 4, 5, 6 };
Test1 test = new Test1();
x = test.shiftArray(x, 2);
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + " ");
}
}
public int[] pushFirstElementToLast(int[] x, int position) {
int temp = x[0];
for (int i = 0; i < x.length - 1; i++) {
x[i] = x[i + 1];
}
x[x.length - 1] = temp;
return x;
}
public int[] shiftArray(int[] x, int position) {
for (int i = position - 1; i >= 0; i--) {
x = pushFirstElementToLast(x, position);
}
return x;
}
}
A left rotation operation on an array of size n shifts each of the array's elements unit to the left, check this out!!!!!!
public class Solution {
private static final Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
String[] nd = scanner.nextLine().split(" ");
int n = Integer.parseInt(nd[0]); //no. of elements in the array
int d = Integer.parseInt(nd[1]); //number of left rotations
int[] a = new int[n];
for(int i=0;i<n;i++){
a[i]=scanner.nextInt();
}
Solution s= new Solution();
//number of left rotations
for(int j=0;j<d;j++){
s.rotate(a,n);
}
//print the shifted array
for(int i:a){System.out.print(i+" ");}
}
//shift each elements to the left by one
public static void rotate(int a[],int n){
int temp=a[0];
for(int i=0;i<n;i++){
if(i<n-1){a[i]=a[i+1];}
else{a[i]=temp;}
}}
}
You can use the Below codes for shifting not rotating:
int []arr = {1,2,3,4,5,6,7,8,9,10,11,12};
int n = arr.length;
int d = 3;
Programm for shifting array of size n by d elements towards left:
Input : {1,2,3,4,5,6,7,8,9,10,11,12}
Output: {4,5,6,7,8,9,10,11,12,10,11,12}
public void shiftLeft(int []arr,int d,int n) {
for(int i=0;i<n-d;i++) {
arr[i] = arr[i+d];
}
}
Programm for shifting array of size n by d elements towards right:
Input : {1,2,3,4,5,6,7,8,9,10,11,12}
Output: {1,2,3,1,2,3,4,5,6,7,8,9}
public void shiftRight(int []arr,int d,int n) {
for(int i=n-1;i>=d;i--) {
arr[i] = arr[i-d];
}
}
import java.util.Scanner;
public class Shift {
public static void main(String[] args) {
Scanner input = new Scanner (System.in);
int array[] = new int [5];
int array1[] = new int [5];
int i, temp;
for (i=0; i<5; i++) {
System.out.printf("Enter array[%d]: \n", i);
array[i] = input.nextInt(); //Taking input in the array
}
System.out.println("\nEntered datas are: \n");
for (i=0; i<5; i++) {
System.out.printf("array[%d] = %d\n", i, array[i]); //This will show the data you entered (Not the shifting one)
}
temp = array[4]; //We declared the variable "temp" and put the last number of the array there...
System.out.println("\nAfter Shifting: \n");
for(i=3; i>=0; i--) {
array1[i+1] = array[i]; //New array is "array1" & Old array is "array". When array[4] then the value of array[3] will be assigned in it and this goes on..
array1[0] = temp; //Finally the value of last array which was assigned in temp goes to the first of the new array
}
for (i=0; i<5; i++) {
System.out.printf("array[%d] = %d\n", i, array1[i]);
}
input.close();
}
}
Write a Java program to create an array of 20 integers, and then implement the process of shifting the array to right for two elements.
public class NewClass3 {
public static void main (String args[]){
int a [] = {1,2,};
int temp ;
for(int i = 0; i<a.length -1; i++){
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
for(int p : a)
System.out.print(p);
}
}

Merging arrays but getting Array index out of bound exception

I am trying to merge two sorted arrays, that is check is A[i] is less than B[j] then create an Array C[k] to store the new array of merged arrays, my problem however is I am getting a java.lang.ArrayIndexOutOfBoundsException: How can I solve this error:
The Last two for loops are to check if we are done comparing A and B and some elements are left move them to C. Here I am assuming A and B is sorted. m and n is size of the Arrays.
Any help will be appreciated Code below:
public class MergeArrays {
public static void main(String[] args) {
// TODO Auto-generated method stub
//given two arrays merge them
int a [] = {2,8,15,18,19,20};
int b [] = {5,9,12,17};
System.out.println(Arrays.toString(mergeArrays(a,b,5,3)));
}
private static int[] mergeArrays(int[] A, int[] B, int m, int n) {
// TODO Auto-generated method stub
int i =1;
int j = 1;
int k = 1;
int C [] = new int [1];
while(i <= m && j <= n) {
if(A[i] < B[j]) {
C[k++] = A[i++];
}else {
C[k++] = B[j++];
}
}
for(; i<=m ; i++) {
C[k++] = A[i];
}
for(; j <= n; j++) {
C[k++] = B[j];
}
return C;
}
}
int C [] = new int [8];
Please provide proper array length in above line. You are providing array length to 1 and k++/i++ values are exceeding to 1 so it is giving ArrayIndexOutOfBoundsException.
You aren't resetting your counters before entering your for loops.
edit: You are also checking if your current counter is less than or equals 5 for example which will throw you an index out of bounds error anyway because arrays start at index 0. But you also try to reach for the incremented index within your brackets "A[i++]" which is going to exceed the index limit too.
edit2: Your "C[]" is also initalized with the size of [1] which means it has following indexes: {0,1}. You set your "k" counter to 1 but once you reach for an index in your "C[]" array you are putting k incremented: "C[k++]", now you are trying to reach for index 2 which doesn't exist. Rewrite your code. I advice you to use inner counters and just use your_array_name.length() to get your array length. eg. for(int i = 0; i < array.length(); i++)
There are couple of mistakes you are doing, just I'll point out so you can fix it.
Array 'C' size should be equal to Length of array 'A' + Length of array 'B.
In Java, array index start with 0 and end with Array length -1.
Your can create class like this,
public static void main(String[] args) {
// TODO Auto-generated method stub
//given two arrays merge them
int a[] = {2, 8, 15, 18, 19, 20};
int b[] = {5, 9, 12, 17};
System.out.println(Arrays.toString(mergeArrays(a, b, a.length, b.length)));
}
private static int[] mergeArrays(int[] A, int[] B, int m, int n) {
int[] C = null;
if (m > n) {
C = A;
for (int i = 0; i < n; i++) {
if (A[i] < B[i]) {
C[i] = B[i];
}
}
} else {
C = B;
for (int i = 0; i < n; i++) {
if (A[i] > B[i]) {
C[i] = A[i];
}
}
}
return C;
}

Recursive Selection Sort in Java

I need to implement this algorithm creating a new ArrayList object at each recursive call.
My starting Array contains integers in this order"20, 40 ,10, 30 ,50 ,5" , after sorting it I have 5,5,5,5,5,5. I think that the problem is in the recursive call and in the last for cicle of the SelectionSort because removing the last for I notice that the the first element is sorted correctly.
import java.util.*;
public class SelectionSort {
//var
public ArrayList<Integer> arr ;
//constructor
public SelectionSort(ArrayList<Integer> arr){
this.arr = arr;
}
public ArrayList<Integer> getarraylist() {
return arr;
}
public void sort(){
//position of the last sorted element
int minimum =0;
if (arr.size() <=0 ) return;
for ( int j = 1; j < arr.size()-1; j++ ) {
if (arr.get(j) < arr.get(0) ) {
minimum = j;
//swap element 0 and minimum
int temp = arr.get(0);
arr.set(0, arr.get(minimum));
arr.set(minimum, temp);
}
}
//recursive call, new array without first element (already sorted)
ArrayList<Integer> arr2 = new ArrayList<>(arr.subList(1,arr.size()));
SelectionSort s2 = new SelectionSort(arr2);
s2.sort();
for(int i=0;i<s2.getarraylist().size();i++) {
arr.set(i, s2.getarraylist().get(i));
}
}
Driver class
public class Main {
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<Integer (Arrays.asList(20,40,10,30,50,5));
System.out.println("\n ARRAY ELEMENTS \n ");
for (int i: arr) {
System.out.println(i);
}
System.out.println("\n SORTED ELEMENTS \n ");
SelectionSort s = new SelectionSort(arr);
s.sort();
for (int i: s.getarraylist()) {
System.out.println(i);
}
}
}
You have actually two bugs in your algorithm that, together, lead to the observed output.
The first bug is within the for-loop that determines the minimal element:
for ( int j = 1; j < arr.size()-1; j++ ) { ...
You terminate one element too early, i.e. the last element is never considered. Thus, after the first iteration, the 5 is the last element in your ArrayList. In fact, it is the last element in every of your ArrayLists. The fix is to not subtract 1 in the for-condition:
for ( int j = 1; j < arr.size(); j++ ) { ...
The second bug is in your last for-loop where you copy the values from index i of s2 to index i of arr. You neglect the fact that s2 is one element shorter than arr. Thus, the only element not overriden is the last element. The fix is to get the i-th element from s2, but write it at the i + 1-th index of arr:
arr.set(i + 1, s2.getarraylist().get(i));
Now let us take look at how those two bugs lead to the observed output. Since
the last element in your ArrayList is never overridden and
the last element is always the same,
all elements have the same value (in your test case: 5).
Some remarks on your code:
the variable minimum is superfluous and can be replaced with j.
If you replace all occurences of ArrayList in SelectionSort with List, you can actually simplify the last part of your code to:
// remove the line declaring arr2, it is no longer needed
SelectionSort s2 = new SelectionSort(arr.subList(1, arr.size()));
s2.sort();
// last for-loop not needed anymore, method ends here
This is possible because ArrayList#subList(...) states that "The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa."
You should take a little bit more care wrt. indentation.
You have some minor inconsistencies in your coding style. For example, sometimes you write a blank after ( or before a ) or {, sometimes you do not. See what you like more and use it uniformly.
In Java, variable-, parameter- and methodnames should be written in camelCase (getarraylist() -> getArrayList())
With your last loop:
for(int i=0;i<s2.getarraylist().size();i++) {
arr.set(i, s2.getarraylist().get(i));
}
This overrides every element with the same number. (Why you got all 5's as your result) This is because you only iterate to the second to last element (arr.size()-1). Then you copy the elements in the line:
ArrayList<Integer> arr2 = new ArrayList<>(arr.subList(1,arr.size()));
Eventually you are only copying the last element over (5) and then copying this to the final ArrayList arr.
Also you create another SelectionSort object every time you call the sort method. This is not good.
Here is the code I wrote:
public void sort(List<Integer> list){
//position of the last ordered element
int minimum =0;
if (list.size() <=0 ) return;
for ( int j = 1; j < list.size(); j++ ) {
if (list.get(j) < list.get(0) ) {
minimum = j;
//swap element 0 and minimum
int temp = list.get(0);
list.set(0, list.get(minimum));
list.set(minimum, temp);
}
}
sort(list.subList(1,list.size()));
}
I changed it to accept an argument of List<Integer> (Because the subList() method returns a List) and then got rid of the last loop and where you created new objects.
Also youll have to change
s.sort();
to:
s.sort(s.getarraylist());
Output:
ARRAY ELEMENTS
20
40
10
30
50
5
SORTED ELEMENTS
5
10
20
30
40
50
Im not sure I understand the question, but I created a recursive (and iterative) selectionSort and InsertionSort just for fun, hope it helps.
public class Sorts {
public static void swap(Comparable[] a, int i, int j) {
Comparable temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void selectionSortItr(Comparable[] a, int n) {
for (int i = 0; i < n - 1; i++) {
int f = i;
for (int j = i + 1; j < n; j++) {
if (a[j].compareTo(a[f]) < 0)
f = j;
}
swap(a, i, f);
}
}
public static int select(Comparable[] a, int n, int j, int f) {
if (j >= n)
return f;
if (a[j].compareTo(a[f]) < 0)
f = j;
return select(a, n, j + 1, f);
}
public static void selectionSort(Comparable[] a, int n, int i) {
if (i < n - 1) {
swap(a, i, select(a, n, i + 1, i));
selectionSort(a, n, i + 1);
}
}
public static void insertionSortItr(Comparable[] a) {
for (int i = 1; i < a.length; i++) {
int j;
Comparable cur = a[i];
for (j = i; j > 0 && cur.compareTo(a[j - 1]) < 0; j--) {
a[j] = a[j - 1];
}
a[j] = cur;
}
}
public static void insertionSortInner(Comparable[] a, Comparable cur, int j) {
if (j > 0 && cur.compareTo(a[j - 1]) < 0) {
a[j] = a[j - 1];
insertionSortInner(a, cur, j - 1);
} else {
a[j] = cur;
}
}
public static void insertionSort(Comparable[] a, int i, int n) {
if (i < n) {
insertionSortInner(a, a[i], i);
insertionSort(a, i + 1, n);
}
}
public static void main(String[] args) {
Integer[] a = new Integer[10];
for (int i = 0; i < 10; i++)
a[i] = (int) (Math.random()*100);
selectionSort(a, 10, 0);
for (int i = 0; i < 10; i++)
System.out.println(a[i]);
}
}

Error trying to sum two different length arrays

I'm trying to make it so the elements of each array are added together to get a sum, regardless if one array is larger than the other. This is the error I'm getting
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
The error is linked to line 13 or 23 depending on which array is bigger in my test class.
( pickedList[i] = listA[i] + listB[i]; are the error lines)
Edit: The code works if the arrays have the same number of elements, but when one is larger it crashes.
public static int[] AddArray(int[] listA, int[] listB)
{
int aLen = listA.length;
int bLen = listB.length;
int[] pickedList = null;
//if array 1 is longer, make picklist have same number of elements then add
//both array elements together
if (aLen >= bLen)
{ pickedList = new int[aLen];
for( int i = 0; i < aLen; i ++)
{
pickedList[i] = listA[i] + listB[i];
}
}
//if array 2 is longer, make picklist have same number of elements then add
//both array elements together
else
{
pickedList = new int[bLen];
for( int i = 0; i < bLen; i ++)
{
pickedList[i] = listA[i] + listB[i] ;
}
}
return pickedList;
}
}
Your error is very simple:
if (aLen >= bLen)
{ pickedList = new int[aLen];
for( int i = 0; i < aLen; i ++)
{
pickedList[i] = listA[i] + listB[i];
you have that.
If alen is longer than blen, then if your forloop goes up to the length of a, you'll get an error because you have listB[i] - you're trying to access elements of B that just aren't there.
Let me make this clearer. Let's say array a has a length of 5, and array b has a length of 3. a is bigger than b, so you loop through i from 0 to 5. Everything will be fine fine for i = 0, i = 1, i = 2, but once you get to i = 3, there is no listB[i], because list B only has an elemnet in the 0, 1, and 2 position, so you get the error that you got.
I hope that helps. Good luck :)
I would use Math.max(int,int) to get the max length. Then declare the new array, then iterate the length adding the elements like
public static int[] addArray(int[] listA, int[] listB) {
int aLen = listA.length;
int bLen = listB.length;
int len = Math.max(aLen, bLen);
int[] pickedList = new int[len];
for (int i = 0; i < len; i++) {
if (i < aLen && i < bLen) {
pickedList[i] = listA[i] + listB[i];
} else if (i < aLen) {
pickedList[i] = listA[i];
} else {
pickedList[i] = listB[i];
}
}
return pickedList;
}
For your first if statement you have aLen >= bLen Then you loop for the length of aLen in a for loop. Inside this for loop, you try to access the elements of listB at index i. However, since listA is longer, the element listB[i] will not exist as the length of listA is longer than the length of listB.
public static int[] AddArray(int[] listA, int[] listB)
{
int smallList[], bigList[], sums[];
int pos;
if (listA.length >= listB.length) {
smallList = listB;
bigList = listA;
} else {
smallList = listA;
bigList = listB;
}
sums = new int[bigList.length];
for (pos=0; pos < smallList.length; ++pos) {
sums[pos] = smallList[pos] + bigList[pos];
}
for (; pos < bigList.length; ++pos) {
sums[pos] = bigList[pos];
}
return sums;
}
If two arrays are
arr1 = [1, 2, 3, 4, 5]
arr2 = [6, 7, 8]
The we can use lower length of two arrays as loop condition (ind < lower_length) to get rid from exception. eg,
int array1_length = arr1.length; // 5
int array2_length = arr1.length; // 3
Then we can get lower limit such ways
int limit = (array1_length > array2_length) ? array2_length : array1_length;
or
int limit = Math.max(array1_length, array2_length);
Then can use the limit in for loop, eg,
for(int ind = 0; ind < limit; ind++){
//sum = arr1[ind] + arr2[ind];
}
I hope it will help you deeply.
try this:
public static int[] AddArray(int[] listA, int[] listB)
{
int aLen = listA.length;
int bLen = listB.length;
int[] pickedList = null;
int i,j;
//if array 1 is longer, make picklist have same number of elements then add
//both array elements together
if (aLen >= bLen)
{ pickedList = new int[aLen];
for( i = 0; i < bLen; i ++)
{
pickedList[i] = listA[i] + listB[i];
}
for( j = i; j < aLen; j++) // listB exhaust so add remaining elements of listA to pickedList
{
pickedList[j] = listA[j] ;
}
}
//if array 2 is longer, make picklist have same number of elements then add
//both array elements together
else
{
pickedList = new int[bLen];
for( i = 0; i < aLen; i ++)
{
pickedList[i] = listA[i] + listB[i] ;
}
for( j = i; j < bLen; j ++)// listA exhaust so add remaining elements of listB to pickedList
{
pickedList[j] = listB[j];
}
}
return pickedList;
}

combining and sorting two arrays Java?

So basically there are two separate presorted arrays, and you have to combine them and sort them (without sort() methods of course). Here is my code:
public static void main(String[] args) {
int a [] = {3,5,7,9,12,14, 15};
int b [] = {6 ,7, 10};
int j = 0;
//output array should be 3,5,6,7,7,9,10,12,14,15
int c [] = new int[a.length+b.length];//10 values
for (int i = 0;i<b.length;i++){
while(b[i]>a[j]){
c[j] = a[j] ;
j++;
}
if(b[i] == a[j]){
c[j] = b[i];
c[j+1] = a[j];
}
c[j] = b[i];
j++;
}
for(int i = 0;i<c.length;i++)
System.out.println(c[i]);
}
I'm guessing the zeros I am getting are from a mistake in one of the booleans (< & >), but I cant seem to figure it out. It works fine for the first 4, but once I get to the repeating 7's, it just goes crazy.
Please help me understand, don't just change the code.
This is how it should be in a simple way:
public static void main(String[] args) {
int a [] = {3,5,7,9,12,14, 15};
int b [] = {6 ,7, 10};
int j = 0, k = 0;
//output array should be 3,5,6,7,7,9,10,12,14,15
int c [] = new int[a.length+b.length];//10 values
// we're filling c with the next appropriate number
// we start with checking a[0] and b[0] till we add
// all the elements
for (int i = 0; i < c.length; i++) {
// if both "a" and "b" have elements left to check
if (j < a.length && k < b.length) {
// check if "b" has a smaller element
if (b[k] < a[j]) {
// if so add it to "c"
c[i] = b[k];
k++;
}
// if "a" has a smaller element
else {
// add it to "c"
c[i] = a[j];
j++;
}
}
// if there are no more elements to check in "a"
// but there are still elements to check in "b"
else if (k < b.length) {
// add those elements in "b" to "c"
c[i] = b[k];
k++;
}
// if there are no more elements to check in "b"
// but there are still elements to check in "a"
else {
// add those elements in "a" to "c"
c[i] = a[j];
j++;
}
}
for(int i = 0; i < c.length; i++)
System.out.println(c[i]);
}
Hope it helps.
You can try this code.
public static void main(String[] args) {
int a[] = { 3, 5, 7, 9, 12, 14, 15 };
int b[] = { 6, 7, 10 };
// output array should be 3,5,6,7,7,9,10,12,14,15
int alen = a.length;
int blen = b.length;
int c[] = new int[a.length + b.length];// 10 values
int s[] = null;
int[] l = null;
if (alen < blen) {
s = a;
l = b;
} else {
s = b;
l = a;
}
// Constructing Combined Array
for (int i = 0, p = 0; i < c.length; i++, p++) {
if (i == s.length) {
p = 0;
}
if (i < s.length) {
c[i] = s[p];
} else {
c[i] = l[p];
}
}
//Sorting the C array
for (int i = 1; i < c.length; i++) {
int j = i;
int B = c[i];
while ((j > 0) && (c[j - 1] > B)) {
c[j] = c[j - 1];
j--;
}
c[j] = B;
}
for (int i = 0; i < c.length; i++)
System.out.print(c[i]);
}
Actually it's better to say merging (not combining) two arrays.
Simple algorithm (taken from this article) for merging sorted arrays A and B[0..n-1] into result C[0..m+n-1]:
Introduce read-indices i, j to traverse arrays A[0..m-1] and B, accordingly. Introduce write-index k to store position of the first free cell in the resulting array. By default i = j = k = 0.
At each step: if both indices are in range (i < m and j < n), choose minimum of (A[i], B[j]) and write it to C[k]. Otherwise go to step 4.
Increase k and index of the array, algorithm located minimal value at, by one. Repeat step 2.
Copy the rest values from the array, which index is still in range, to the resulting array.
Hope it helps.
Use ai and bi for the indices in both source arrays and ci as the index for the destination array.
You only need one loop.
Try to keep this very clear and advance in c by exactly one element at each iteration.
In the loop, check wether the end of one array was reached. If so, just take an element from the other array. Otherwise, take only the smaller element of a[ai] and b[bi] and increment the corresponding index.
It is very easy to make mistakes in mergesort (or in any code where two arrays need to be walked in parallel) by thinking "hey I can go along with a while loop instead of just doing a single if", but then you typically have two loops nested in a third one, and for each of the loops you have to do the right bounds checks, and there is typically no significant gain in performance.
p.s. Doing one main loop and then two cleanup loops after the main loop is fine, just avoid nested loops if they are not necessary, in particular in interviews where this may also cause confusion when calculating the runtime.
Try this, your error is you are using the same cellular index for array A and array C:
public class MainClass {
public static void main(String[] args) {
int[] arrayA = { 23, 47, 81, 95 };
int[] arrayB = { 7, 14, 39, 55, 62, 74 };
int[] arrayC = new int[10];
merge(arrayA, arrayA.length, arrayB, arrayB.length, arrayC);
for (int i : arrayC) {
System.out.println(i);
}
}
public static void merge(int[] arrayA, int sizeA, int[] arrayB, int sizeB, int[] arrayC) {
int arrayAIndex = 0, arrayBIndex = 0, arrayCIndex = 0;
while (arrayAIndex < sizeA && arrayBIndex < sizeB)
if (arrayA[arrayAIndex] < arrayB[arrayBIndex])
arrayC[arrayCIndex++] = arrayA[arrayAIndex++];
else
arrayC[arrayCIndex++] = arrayB[arrayBIndex++];
while (arrayAIndex < sizeA)
arrayC[arrayCIndex++] = arrayA[arrayAIndex++];
while (arrayBIndex < sizeB)
arrayC[arrayCIndex++] = arrayB[arrayBIndex++];
}
}
This is another version
// size of C array must be equal or greater than
// sum of A and B arrays' sizes
public void merge(int[] A, int[] B, int[] C) {
int i, j, k, m, n;
i = 0;
j = 0;
k = 0;
m = A.length;
n = B.length;
while (i < m && j < n) {
if (A[i] <= B[j]) {
C[k] = A[i];
i++;
} else {
C[k] = B[j];
j++;
}
k++;
}
if (i < m) {
for (int p = i; p < m; p++) {
C[k] = A[p];
k++;
}
} else {
for (int p = j; p < n; p++) {
C[k] = B[p];
k++;
}
}
}
public class Combinearray {
public static void main(String[] args) {
int[] array1= {5,4,6,2,1};
int[] array2= {2,5,8,4,1,6,4};
int m=array1.length;
int n=array2.length;
int[] array3=new int[m+n];
int a=1;
for(int i=0;i<m;i++) {
array3[i]=array1[i];//array1 is copied to array3
}
for(int i=0;i<n;i++) {
array3[m-1+a]=array2[i];//array2 is copied to array3
a++;
}
//array3 is combined array
int l=array3.length;
int temp[]=new int[l];
for(int i=0;i<l;i++) {
for(int j=i+1;j<l;j++) {
if(array3[i]>array3[j]) {
temp[i]=array3[i];
array3[i]=array3[j];
array3[j]=temp[i];
}
}
}
System.out.println("sorted array is ");
System.out.print("[");
for(int i=0;i<l;i++) {
System.out.print(array3[i]+" ");
}
System.out.print("]");
}
}

Categories