How can I cut a section of an array in java - java

I have to write a method in java, where having in input an array "a" of numbers and a number "x" returns an array of elements which follows the last occorence of "x " in "a". For example
with input {0,1,2,3,4,5,6,7,8,9} and x=6 the method must return {7,8,9} meanwhile with {4,1,4,2} and x =4 the method must return {2} and if the x is not in "a" then it must return empty array {} (or array with 0 length)
so far we haven't study classes or objects .here an example of another program we made so far
boolean arrayIncluso( int[] s,int[] t ) {
boolean flag=true;
for(int i=0;i< s.length;i++){
int c1 = 0 ;
int c2 = 0 ;
for(int j=0;j< s.length;j++){
if(s[i] == s[j]){
c1 ++;
}
}
for(int j=0;j< t.length;j++){
if(s[i] == t[j]){
c2 ++;
}
}
if(c1 > c2)
flag= false;
}
return flag;
}
can someone explain to me
why this
t[i-idx-1 ] = s[i];
instead of this
for(int j=0;j<t.length;j++){
t[j]=a[i];
}
return t;

You can split the problem into two parts:
Find last index of the character x. This can be done using an easy for loop.
int idx = -1;
for (int i = 0; i < s.length; i++) {
if (s[i] == x) idx = i;
}
After you found this index, create a new array starting from this element. It can be done with a second (not nested) for loop, or you can use Arrays.copyOfRange()
//make sure idx != -1
int[] t = new int[s.length - idx - 1];
for (int i = idx+1; i < s.length; i++)
t[i-idx-1 ] = s[i];
System.out.println(Arrays.toString(t)); //print to make sure it's all fine
OR
t = Arrays.copyOfRange(s, idx+1, s.length);
System.out.println(Arrays.toString(t));

Here's a general algorithm: (you have to code it yourself)
Run through the array a keeping track of the current index of the number x. Call this index e.g.lastOccurance.
Return the array from lastOccurance + 1 and onwards.
Don't forget checks for no occurances and if the last occurance is end of array.

Using lists:
int pos = a.lastIndexOf(x);
List<Integer> result = null;
if(pos > -1)
result = a.subList(pos+1, a.size());
You can build your the list from an arra y using Arrays:
Integer [] array = new Integer[3];
...
...
List<Integer> a = Arrays.asList(array);
Alltogether would result in a code like:
List<Integer> a = Arrays.asList(array);
int pos = a.lastIndexOf(x);
int [] result = null;
if(pos > -1) {
List<Integer> sl = a.subList(pos+1, a.size());
result = new int[sl.size()];
for(int i = 0; i < sl.size(); i++)
result[i] = sl.get(i);
}

You can use commons lang library in order to determine the last index of an array element with method ArrayUtils.lastIndexOf, that way it turns to be a one-liner:
int[] t = Arrays.copyOfRange(s, ArrayUtils.lastIndexOf(s, x) + 1, s.length);

Related

Find possible pairs from binary string

I have an array of strings with values only 0 and 1.
Example:
["100" , "110", "010", "011", "100"]
Now I want to take each string and compare it with all other strings and see how many of them differ by 1. For example:
"100" compared with "110", the element at each index is checked, if they are different by a maximum of 1 position then they are considered similar. So for String "100" in above array, the similar elements are "110" and "100".
My program returns an array of integers where each value indicates the number of similar strings at that index in list.
Example:
Input :
["100" , "110", "010", "011", "100"]
Output:
[2,3,2,1,2]
Explanation:
At index 1, input is "110" the similar strings are 3 which are "100", "010", "100".
Here is my code:
static List<Integer> process(String[] input) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < input.length; i++) {
int count = 0;
for (int j = 0; j < input.length; j++) {
if (i != j) {
int differ = 0;
for (int k = 0; k < input[i].length(); k++) {
if (input[i].charAt(k) != input[j].charAt(k)) {
differ++;
}
if (differ > 1) {
break;
}
}
if (differ <= 1) {
count++;
}
}
}
list.add(count);
}
return list;
}
How can I improve the time complexity of this code?
All Strings are of the same length and the length ranges from 1 to 20. Size of input array is up to 10,000.
We can exploit the fact that all input strings are of the same length to build a simple binary radix tree over the characters 0 and 1, and store the count of matching strings in the leaves.
You can then use a recursive function to navigate the tree for each input string, considering at most one divergence, where you visit the child with the opposite character. You sum all the leaf nodes reached in this manner.
First we build the tree:
static class Node
{
Node[] child = new Node[2];
int count;
}
static Node buildTree(String[] s)
{
Node root = new Node();
for(String bs : s)
{
Node node = root;
for(char c : bs.toCharArray())
{
int i = c - '0';
if(node.child[i] == null)
node.child[i] = new Node();
node = node.child[i];
}
node.count++;
}
return root;
}
Then we use recursion to count matching strings. Note that if we reach the leaf and diff is 0, i.e. we've located the original string, then we need to reduce the count by 1, as we're not counting self-matches.
static int countDiff(Node node, String s, int pos, int diff)
{
if(pos == s.length())
return diff == 0 ? node.count-1 : node.count;
int i = s.charAt(pos) - '0';
int sum = 0;
if(diff == 0 && node.child[(i+1)%2] != null)
sum += countDiff(node.child[(i+1)%2], s, pos+1, 1);
if(node.child[i] != null)
sum += countDiff(node.child[i], s, pos+1, diff);
return sum;
}
Test:
String[] s = {"100" , "110", "010", "011", "100"};
Node root = buildTree(s);
int[] count = new int[s.length];
for(int i=0; i<s.length; i++)
count[i] = countDiff(root, s[i], 0, 0);
System.out.println(Arrays.toString(count));
Output:
[2, 3, 2, 1, 2]
I really like RaffleBuffle's answer which uses radix trees.
But just as a faster-to-implement alternative — you might instead use int[] as a frequency map: index i stores how many copies of number i are in input.
The size of the frequency map array depends on the width of input strings — so it's up to int[220] == int[1'048'576].
static List<Integer> process(String[] input) {
var bitWidth = input[0].length();
var values = new int[input.length];
var freqMap = new int[1 << bitWidth]; // 2^bitWidth;
// fill values and frequency map
for (var i = 0; i < values.length; i++) {
var value = toInt(input[i]);
values[i] = value;
freqMap[value]++;
}
var result = new ArrayList<Integer>(values.length);
// fill results
for (var value : values) {
var numClose = freqMap[value] - 1;
// close value: one bit flipped
for (var iBit = 0; iBit < bitWidth; iBit++) {
var closeVal = flipBit(value, iBit);
numClose += freqMap[closeVal];
}
result.add(numClose);
}
return result;
}
private static int toInt(String inputValue) {
var result = 0;
for (int pos = inputValue.length() - 1, posWeight = 1; pos >= 0; pos--, posWeight <<= 1) {
if (inputValue.charAt(pos) == '1') {
result += posWeight;
}
}
return result;
}
private static int flipBit(int value, int bitPosition) {
return value ^ (1 << bitPosition);
}
A Frankenstein answer combined from:
using Set (actually HashMap to support repeating input numbers) as in talex's answer
using Integer.valueOf(String, 2) to convert input to int numbers as in GURU Shreyansh's answer
using bit fliping to compute close values as in user16394029's answer
The code we get:
static List<Integer> process(String[] input) {
var values = new ArrayList<Integer>(input.length);
var freqMap = new HashMap<Integer, Integer>(input.length);
var bitWidth = input[0].length();
for (var inputValue : input) {
var value = Integer.parseInt(inputValue, 2);
values.add(value);
freqMap.compute(value, (key, old) -> (old == null) ? 1 : (old + 1));
}
for (var i = 0; i < values.size(); i++) {
var value = values.get(i);
var numClose = freqMap.get(value) - 1;
for (var iBit = 0; iBit < bitWidth; iBit++) {
numClose += freqMap.getOrDefault(flipBit(value, iBit), 0);
}
values.set(i, numClose);
}
return values;
}
private static int flipBit(int value, int bitPosition) {
return value ^ (1 << bitPosition);
}
You can use set.
Put all strings in set s
For each string generate all string that differs by single change
Count number of generated strings that belong to s
It will have complexity of O(n*m*m) instead of O(n*n*m) your algorithm have.
n is number of strings and m is length of string.
So it is better in regards of n, but worse in regards of m.
Also it requires O(n*m) memory. Original algorithm requires O(max(log(n), log(m))) memory.
For better performance convert strings to integers.
I can suggest an O(N^2) approach using bitwise XOR. The result of XOR is 1 if the two bits are different. So, we can use this property to find the count of positions where the bit are different.
int[] num = new int[input.length];
for (int i = 0; i < input.length; i++)
num[i] = Integer.valueOf(input[i], 2); // converting to integral form
for (int i = 0; i < input.length; i++)
{
int count = 0;
for (int j = 0; j < input.length; j++)
{
if (i == j) // skip
continue;
if (Integer.bitCount(num[i] ^ num[j]) <= 1) // similar
{
++count;
}
}
list.add(count);
}
I've used bitCount method of java.lang package which returns the count of the number of one-bits in the two's complement binary representation of a number to find the set bits in the resultant XOR. Number of set bits in the resultant XOR indicates that that many positions were different between the two numbers.

Need help removing middle element in an array if the length is odd, or the middle two if its even

Basically, one of my assignments is if the array is odd, remove the middle element or if the array is even, remove the middle two elements.
Here is my code, it may be sloppy as this is my first year of high school Java.
public static void removeMiddle(int[] arr)
{
int size = arr.length;
if(size % 2 ==0)
{
int x = arr.length/2 -1;
for(int i = x; i <= arr.length - 2; i++)
{
arr[i] = arr[i + 2];
}
}
else
{
int z = arr.length/2;
for(int i = z; i < arr.length - 1; i++)
{
arr[i] = arr[i + 1];
}
}
}
I was following the pseudo code that the teacher gave us if we got stuck. When I'm running it, it's adding an extra element.
For example, my array 3, 6, -2, 8, 9 changes to 3, 6, 8, 9, 9, after running it
Create a local variable named "size" that stores the length of the array passed in.
* 2. If the size of the array happens to be even, do the following:
* a. Create a local variable that represents the first to remove by assigning it to be one less than
* half the size of the array
* b. Run a for-loop starting at the value you just calculated (representing the first to remove) and
* terminating at two less than the size of the array
* i. In the for-loop, assign the value at the current index of the array to be the value at two
* more than the current index
* 3. Otherwise, given the size of the array happens to be odd, do the following:
* a. Create a local variable that represents the first to remove by assigning it to be half the
* size of the array
* b. Run a for-loop starting at the value you just calculated (representing the first to remove) and
* terminating at one less than the size of the array
* i. In the for-loop, assign the value at the current index of the array to be the value at one
* more than the current index
Any suggestions?
I'm not sure if I understood your questions correctly.
Is it saying, for example, if an array had the size of 8 (8 elements),
the new array returned after the method should return a new array with 6 elements?
I would first, change the return type of the method you provided to be int[].
You can try to implement stack, or queue, or simply stick to using arrays with a bunch of conditionals.
int size = arr.length;
int newArr[];
if(size % 2 ==0) {
newArr = new int[size-2];
for (int i = 0; i < (newArr.length/2); i++) {
newArr[i] = arr[i];
System.out.println(newArr[i]);
}
for (int i = (newArr.length/2); i < newArr.length; i++) {
newArr[i] = arr[i+2];
System.out.println(newArr[i]);
}
}
else {
newArr = new int[size-1];
for(int i = 0; i < (newArr.length/2); i++) {
newArr[i] = arr[i];
System.out.println(newArr[i]);
}
for (int i = (newArr.length/2); i < newArr.length; i++) {
newArr[i] = arr[i+1];
System.out.println(newArr[i]);
}
}
if the input was 123456, this produces 1256
if the input was 12345, this produces 1245
In my opinion, in the "even" if clause, you should just change the
for(int i = x; i <= arr.length - 2; i++)
to
for(int i = x; i < arr.length - 2; i++)
Do you need to get from 1,2,3,4,5,6 an array like 1,2,5,6,5,6 or 1,2,5,6?
To delete the elements from an array, you need to make a new array from the existing one, and then return the result, or change the reference of the original array to the new created array.
public static void removeMiddle(int[] myArray)
{
int size = myArray.length;
int[] resultArray;
if(size % 2 ==0)
{
resultArray = new int [myArray.length-2];
}
else
{
resultArray = new int [myArray.length-1];
}
int mid1 = myArray.length/2;
int mid2 = myArray.length/2 - 1;
int index = 0;
for(int i=0;i<myArray.length;i++)
{
if(size % 2 ==0 && (i==mid1 || i==mid2))
{
continue;
}
else if(!((size % 2) ==0) && i==mid1)
{
continue;
}
resultArray[index] = myArray[i];
index++;
}
for(int i=0;i<resultArray.length;i++)
{
System.out.println("array[" + i + "] = " + resultArray[i]);
}
}
If myArray hold the value as 1,2,3,4,5,6,7 the output will be as below
array[0] = 1
array[1] = 2
array[2] = 3
array[3] = 5
array[4] = 6
array[5] = 7
and if it hole the value as 1,2,3,4,5,6 the output will be as below
array[0] = 1
array[1] = 2
array[2] = 5
array[3] = 6

Getting the most "popular" number from array

I need for homework to get the most "popular" number in an array (the number in the highest frequency), and if there are several numbers with the same number of shows, get some number randomly.
After more then three hours of trying, and either searching the web, this is what I got:
public int getPopularNumber(){
int count = 1, tempCount;
int popular = array[0];
int temp = 0;
for ( int i = 0; i < (array.length - 1); i++ ){
if ( _buses[i] != null )
temp = array[i];
tempCount = 0;
for ( int j = 1; j < _buses.length; j++ ){
if ( array[j] != null && temp == array[j] )
tempCount++;
}
if ( tempCount > count ){
popular = temp;
count = tempCount;
}
}
return popular;
}
This code work, but don't take into account an important case- if there is more than one number with the same count of shows. Then it just get the first one.
for example: int[]a = {1, 2, 3, 4, 4, ,5 ,4 ,5 ,5}; The code will grab 4 since it shown first, and it's not random as it should be.
Another thing- since it's homework I can't use ArrayList/maps and stuff that we still didn't learn.
Any help would be appreciated.
Since they didn't give you any time complexity boundary, you can "brute force" the problem by scanning the the array N^2 times. (disclaimer, this is the most intuitive way of doing it, not the fastest or the most efficient in terms of memory and cpu).
Here is some psuedo-code:
Create another array with the same size as the original array, this will be the "occurrence array"
Zero its elements
For each index i in the original array, iterate the original array, and increment the element in the occurrence array at i each time the scan finds duplicates of the value stored in i in the original array.
Find the maximum in the occurrence array
Return the value stored in that index in the original array
This way you mimic the use of maps with just another array.
If you are not allowed to use collection then you can try below code :
public int getPopularNumber(){
int inputArr[] = {1, 2, 3, 4, 4, 5 ,4 ,5 ,5}; // given input array
int[] tempArr = new int[inputArr.length];
int[] maxValArr = new int[inputArr.length];
// tempArr will have number as index and count as no of occurrence
for( int i = 0 ; i < inputArr.length ; i++){
tempArr[inputArr[i]]++;
}
int maValue = 0;
// find out max count of occurrence (in this case 3 for value 4 and 5)
for( int j = 0 ; j < tempArr.length ; j++){
maValue = Math.max(maValue, tempArr[j]);
}
int l =0;
// maxValArr contains all value having maximum occurrence (in this case 4 and 5)
for( int k = 0 ; k < tempArr.length ; k++){
if(tempArr[k] == maValue){
maxValArr[l] = k;
l++;
}
}
return maxValArr[(int)(Math.random() * getArraySize(maxValArr))];
}
private int getArraySize(int[] arr) {
int size = 0;
for( int i =0; i < arr.length ; i++){
if(arr[i] == 0){
break;
}
size++;
}
return size;
}
that's hard as hell :D
After some trying, I guess I have it (If there will be 2 numbers with same frequency, it will return first found):
int mostPopNumber =0;
int tmpLastCount =0;
for (int i = 0; i < array.length-1; i++) {
int tmpActual = array[i];
int tmpCount=0;
for (int j = 0; j < array.length; j++) {
if(tmpActual == array[j]){
tmpCount++;
}
}
// >= for the last one
if(tmpCount > tmpLastCount){
tmpLastCount = tmpCount;
mostPopNumber = tmpActual;
}
}
return mostPopNumber;
--
Hah your code give me idea- you cant just remember last most popular number, btw I've found it solved there Find the most popular element in int[] array
:)
EDIT- after many, and many years :D, that works well :)
I've used 2D int and Integer array - you can also use just int array, but you will have to make more length array and copy actual values, Integer has default value null, so that's faster
Enjoy
public static void main(String[] args) {
//income array
int[] array= {1,1,1,1,50,10,20,20,2,2,2,2,20,20};
//associated unique numbers with frequency
int[][] uniQFreqArr = getUniqValues(array);
//print uniq numbers with it's frequency
for (int i = 0; i < uniQFreqArr.length; i++) {
System.out.println("Number: " + uniQFreqArr[i][0] + " found : " + uniQFreqArr[i][1]);
}
//get just most frequency founded numbers
int[][] maxFreqArray = getMaxFreqArray(uniQFreqArr);
//print just most frequency founded numbers
System.out.println("Most freq. values");
for (int i = 0; i < maxFreqArray.length; i++) {
System.out.println("Number: " + maxFreqArray[i][0] + " found : " + maxFreqArray[i][1]);
}
//get some of found values and print
int[] result = getRandomResult(maxFreqArray);
System.out.println("Found most frequency number: " + result[0] + " with count: " + result[1]);
}
//get associated array with unique numbers and it's frequency
static int[][] getUniqValues(int[] inArray){
//first time sort array
Arrays.sort(inArray);
//default value is null, not zero as in int (used bellow)
Integer[][] uniqArr = new Integer[inArray.length][2];
//counter and temp variable
int currUniqNumbers=1;
int actualNum = inArray[currUniqNumbers-1];
uniqArr[currUniqNumbers-1][0]=currUniqNumbers;
uniqArr[currUniqNumbers-1][1]=1;
for (int i = 1; i < inArray.length; i++) {
if(actualNum != inArray[i]){
uniqArr[currUniqNumbers][0]=inArray[i];
uniqArr[currUniqNumbers][1]=1;
actualNum = inArray[i];
currUniqNumbers++;
}else{
uniqArr[currUniqNumbers-1][1]++;
}
}
//get correctly lengthed array
int[][] ret = new int[currUniqNumbers][2];
for (int i = 0; i < uniqArr.length; i++) {
if(uniqArr[i][0] != null){
ret[i][0] = uniqArr[i][0];
ret[i][1] = uniqArr[i][1];
}else{
break;
}
}
return ret;
}
//found and return most frequency numbers
static int[][] getMaxFreqArray(int[][] inArray){
int maxFreq =0;
int foundedMaxValues = 0;
//filter- used sorted array, so you can decision about actual and next value from array
for (int i = 0; i < inArray.length; i++) {
if(inArray[i][1] > maxFreq){
maxFreq = inArray[i][1];
foundedMaxValues=1;
}else if(inArray[i][1] == maxFreq){
foundedMaxValues++;
}
}
//and again copy to correctly lengthed array
int[][] mostFreqArr = new int[foundedMaxValues][2];
int inArr= 0;
for (int i = 0; i < inArray.length; i++) {
if(inArray[i][1] == maxFreq){
mostFreqArr[inArr][0] = inArray[i][0];
mostFreqArr[inArr][1] = inArray[i][1];
inArr++;
}
}
return mostFreqArr;
}
//generate number from interval and get result value and it's frequency
static int[] getRandomResult(int[][] inArray){
int[]ret=new int[2];
int random = new Random().nextInt(inArray.length);
ret[0] = inArray[random][0];
ret[1] = inArray[random][1];
return ret;
}

Given an array with 2 integers that repeat themselves the same no. of times, how do i print the two integers

i'm new to this, Say if you typed 6 6 6 1 4 4 4 in the command line, my code gives the most frequent as only 6 and i need it to print out 6 and 4 and i feel that there should be another loop in my code
public class MostFrequent {
//this method creates an array that calculates the length of an integer typed and returns
//the maximum integer...
public static int freq(final int[] n) {
int maxKey = 0;
//initiates the count to zero
int maxCounts = 0;
//creates the array...
int[] counts = new int[n.length];
for (int i=0; i < n.length; i++) {
for (int j=0; j < n[i].length; j++)
counts[n[i][j]]++;
if (maxCounts < counts[n[i]]) {
maxCounts = counts[n[i]];
maxKey = n[i];
}
}
return maxKey;
}
//method mainly get the argument from the user
public static void main(String[] args) {
int len = args.length;
if (len == 0) {
//System.out.println("Usage: java MostFrequent n1 n2 n3 ...");
return;
}
int[] n = new int[len + 1];
for (int i=0; i<len; i++) {
n[i] = Integer.parseInt(args[i]);
}
System.out.println("Most frequent is "+freq(n));
}
}
Thanks...enter code here
Though this may not be a complete solution, it's a suggestion. If you want to return more than one value, your method should return an array, or better yet, an ArrayList (because you don't know how many frequent numbers there will be). In the method, you can add to the list every number that is the most frequest.
public static ArrayList<Integer> freq(final int[] n) {
ArrayList<Integer> list = new ArrayList<>();
...
if (something)
list.add(thatMostFrequentNumber)
return list;
}
The solutions looks like this:
// To use count sort the length of the array need to be at least as
// large as the maximum number in the list.
int[] counts = new int[MAX_NUM];
for (int i=0; i < n.length; i++)
counts[n[i]]++;
// If your need more than one value return a collection
ArrayList<Integer> mf = new ArrayList<Integer>();
int max = 0;
for (int i = 0; i < MAX_NUM; i++)
if (counts[i] > max)
max = counts[i];
for (int i = 0; i < MAX_NUM; i++)
if (counts[i] == max)
mf.add(i);
return mf;
Well you can just do this easily by using the HashTable class.
Part 1. Figure out the frequency of each number.
You can do this by either a HashTable or just a simple array if your numbers are whole numbrs and have a decent enough upper limit.
Part 2. Find duplicate frequencies.
You can just do a simple for loop to figure out which numbers are repeated more than once and then print them accordingly. This wont necessarily give them to you in order though so you can store the information in the first pass and then print it out accordingly. You can use a HashTable<Integer,ArrayList<Integer> for this. Use the key to store frequency and the ArrayList to store the numbers that fall within that frequency.
You can maintain a "max" here while inserting into our HashTable if you only want to print out only the things with most frequency.
Here is a different way to handle this. First you sort the list, then loop through and keep track of the largest numbers:
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
int n[] = { 6, 4, 6, 4, 6, 4, 1 };
List<Integer> maxNums = new ArrayList<Integer>();
int max = Integer.MIN_VALUE;
Integer lastValue = null;
int currentCount = 0;
Arrays.sort(n);
for( int i : n ){
if( lastValue == null || i != lastValue ){
if( currentCount == max ){
maxNums.add(lastValue);
}
else if( currentCount > max ){
maxNums.clear();
maxNums.add(lastValue);
max = currentCount;
}
lastValue = i;
currentCount = 1;
}
else {
currentCount++;
}
System.out.println("i=" + i + ", currentCount=" + currentCount);
}
if( currentCount == max ){
maxNums.add(lastValue);
}
else if( currentCount >= max ){
maxNums.clear();
maxNums.add(lastValue);
}
System.out.println(maxNums);
}
}
You can try it at: http://ideone.com/UbmoZ5

"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