Java Arrays: Adding elements of multiple arrays ignoring null arrays - java

I have 5 float arrays all of the same length. At any given time: all, none or some of the arrays may be null (uninitialized).
I am trying to create a function which will add up the values of the arrays and produce a final array with the summed up values in position.
Is there a way to only include the values from the populated arrays?
Thanks,
m

You'd have to check for it. Something like:
/**
* Assumes that all rows are the same length as the first row.
*/
public float[] addValues(float[][] values){
float[] result = new float[values[0].length];
for(float[] row : values){
if(row != null){
for(int i = 0; i < row.length; i++){
result[i] += row[i];
}
}
}
return result;
}

public float[] addUp(float[][] yourArrays) {
if(yourArrays == null)
return null;
int i, j;
int arrayLength = 0;
float[] toReturn = null;
//get the length of the array that will be returned
for(i = 0; i < yourArrays.length; i++) {
if((yourArrays[i] != null) && yourArrays[i].length > arrayLength)
arrayLength = yourArrays[i].length;
}
//now build the array that will be returned, but only if there
//have been any values at all
if(arrayLength != 0) {
//create the array
toReturn = new float[arrayLength];
//fill it
for(i = 0; i < yourArrays.length; i++) {
for(j = 0; j < arrayLength; j++) {
if((yourArrays[i] != null)
&& (j < yourArrays[i].length)
toReturn[j] += yourArrays[i][j];
}
}
}
return toReturn;
}
This should do what you want; it selects only values from arrays that have been initialized, only up until the last element of each array (so you won't have an ArrayOutOfBoundsException) and only if there where any values at all.
Runtime is in O([length of the longest array] * [number of arrays]).
Return values arenull if none of the arrays were initialized or if the longest array that was initialized had a length of 0;
a float[] holding in each cell the sum of all values for which any of your initial arrays had something set.

First of all, array objects have a length, but array references don't. Only a reference can be null (which means that it refers to no object). Your initial problem description is therefore somewhat in error.
But in any case, you can trivially check if an array reference is null:
if (theArray != null) {
// add in contribution from theArray
...

Can you use Float ?
List<Float> newArr = new ArrayList<Float>();
for (float[] arr : arrays)
{
if (arrf != null)
{
for (float number : arr) { newArr.add(number); }
}
}
newArr.toArray(new Float[0]);

yes you can create a final array by the sum size of all the arrays
then you start a for for each array
then if the value is not null you add it to the final
String[] a = new String[5];
String[] b = new String[5];
String[] c = new String[5];
String[] d = new String[5];
String[] e = new String[5];
String[] finalarray = new String[a.length + b.length + c.length + d.length + e.length];
int count = 0;
for (int i = 0; i < a.length; i++) {
if(a[i] != null){
finalarray[count] = a[i];
count++;
}
}
for (int i = 0; i < b.length; i++) {
if(b[i] != null){
finalarray[count] = b[i];
count++;
}
}
for (int i = 0; i < c.length; i++) {
if(c[i] != null){
finalarray[count] = c[i];
count++;
}
}
for (int i = 0; i < d.length; i++) {
if(d[i] != null){
finalarray[count] = d[i];
count++;
}
}
for (int i = 0; i < e.length; i++) {
if(e[i] != null){
finalarray[count] = e[i];
count++;
}
}

Related

How do I remove duplicated strings in an array of strings?

public static String[] dictionary(String s){
int count=0;
String[] ans = sentence(s);
int size = ans.length;
for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < ans.length; j++) {
if (ans[i].compareTo(ans[j]) > 0) {
String temp = ans[i];
ans[i] = ans[j];
ans[j] = temp;
}
}
}
for (int i = 0; i < ans.length; i++) {
ans[i] = [i].to lowerCase);
}
return ans;
}
I have to find duplicated strings and remove them from an array of strings that are sorted lexicographically
Because you know that incoming array sorted, you can get current element and compare next elements with current one. If it is equals skip it, otherwise add this element to the result, and change current. Something like this
public static String[] dictionary(String s){
String[] ans = sentence(s);
if (ans == null || ans.length == 0) {
return ans;
}
List<String> result = new ArrayList<String>();
String current = ans[0];
result.add(current);
for (int i= 1; i < ans.length; i++) {
if (!ans[i].equals(current)) {
result.add(ans[i]);
current = ans[i];
}
}
return result.toArray(new String[0]);
}
If you don't want to use sets, you can do it like this. And it does not require a sorted array. It works as follows. Note: This changes the passed in array.
Get the first element. If it is null continue to next element.
Compare first element to next.
If equal, replace next with a null and increment removed
Continue processing elements.
Now create a new array of original size minus - removed.
And copy all non null values to new array and return it.
public static String[] removeDups(String[] arr) {
// keep track of removed values
int removed = 0;
for (int i = 0; i < arr.length-1; i++) {
for (int j = i+1; j < arr.length; j++) {
if (arr[i] == null) {
// skip this entry and go to next
break;
}
if (arr[i].equals(arr[j])) {
// designate as removed
arr[j] = null;
removed++;
}
}
}
// copy remaining items to new array and return.
String[] result = new String[arr.length-removed];
int k = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] != null) {
result[k++] = arr[i];
}
}
return result;
}
If you want to do it with streams you can do it this way.
String[] result = Arrays.stream(arr).distinct().toArray(String[]::new);
A simple way to do this would be to place them into a set
Set<String> setsHaveNoDuplicates = new HashSet<>(Arrays.asList(ans));
Sets have no duplicates, and if you want to convert the set back to an array of strings, you can do this
String[] result = setsHaveNoDuplicates.toArray(new String[0]);

JAVA - Compare two arrays and create a new array with only the unique values from the first

I have to solve an exercise with the following criteria:
Compare two arrays:
int[] a1 = {1, 3, 7, 8, 2, 7, 9, 11};
int[] a2 = {3, 8, 7, 5, 13, 5, 12};
Create a new array int[] with only unique values from the first array. Result should look like this: int[] result = {1,2,9,11};
NOTE: I am not allowed to use ArrayList or Arrays class to solve this task.
I'm working with the following code, but the logic for the population loop is incorrect because it throws an out of bounds exception.
public static int[] removeDups(int[] a1, int[] a2) {
//count the number of duplicate values found in the first array
int dups = 0;
for (int i = 0; i < a1.length; i++) {
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
dups++;
}
}
}
//to find the size of the new array subtract the counter from the length of the first array
int size = a1.length - dups;
//create the size of the new array
int[] result = new int[size];
//populate the new array with the unique values
for (int i = 0; i < a1.length; i++) {
int count = 0;
for (int j = 0; j < a2.length; j++) {
if (a1[i] != a2[j]) {
count++;
if (count < 2) {
result[i] = a1[i];
}
}
}
}
return result;
}
I would also love how to solve this with potentially one loop (learning purposes).
I offer following soulution.
Iterate over first array, and find out min and max it's value.
Create temporary array with length max-min+1 (you could use max + 1 as a length, but it could follow overhead when you have values e.g. starting from 100k).
Iterate over first array and mark existed values in temorary array.
Iterate over second array and unmark existed values in temporary array.
Place all marked values from temporary array into result array.
Code:
public static int[] getUnique(int[] one, int[] two) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < one.length; i++) {
min = one[i] < min ? one[i] : min;
max = one[i] > max ? one[i] : max;
}
int totalUnique = 0;
boolean[] tmp = new boolean[max - min + 1];
for (int i = 0; i < one.length; i++) {
int offs = one[i] - min;
totalUnique += tmp[offs] ? 0 : 1;
tmp[offs] = true;
}
for (int i = 0; i < two.length; i++) {
int offs = two[i] - min;
if (offs < 0 || offs >= tmp.length)
continue;
if (tmp[offs])
totalUnique--;
tmp[offs] = false;
}
int[] res = new int[totalUnique];
for (int i = 0, j = 0; i < tmp.length; i++)
if (tmp[i])
res[j++] = i + min;
return res;
}
For learning purposes, we won't be adding new tools.
Let's follow the same train of thought you had before and just correct the second part:
// populate the new array with the unique values
for (int i = 0; i < a1.length; i++) {
int count = 0;
for (int j = 0; j < a2.length; j++) {
if (a1[i] != a2[j]) {
count++;
if (count < 2) {
result[i] = a1[i];
}
}
}
}
To this:
//populate the new array with the unique values
int position = 0;
for (int i = 0; i < a1.length; i++) {
boolean unique = true;
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
unique = false;
break;
}
}
if (unique == true) {
result[position] = a1[i];
position++;
}
}
I am assuming the "count" that you implemented was in attempt to prevent false-positive added to your result array (which would go over). When a human determines whether or not an array contains dups, he doesn't do "count", he simply compares the first number with the second array by going down the list and then if he sees a dup (a1[i] == a2[j]), he would say "oh it's not unique" (unique = false) and then stop going through the loop (break). Then he will add the number to the second array (result[i] = a1[i]).
So to combine the two loops as much as possible:
// Create a temp Array to keep the data for the loop
int[] temp = new int[a1.length];
int position = 0;
for (int i = 0; i < a1.length; i++) {
boolean unique = true;
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
unique = false;
break;
}
}
if (unique == true) {
temp[position] = a1[i];
position++;
}
}
// This part merely copies the temp array of the previous size into the proper sized smaller array
int[] result = new int[position];
for (int k = 0; k < result.length; k++) {
result[k] = temp[k];
}
Making your code work
Your code works fine if you correct the second loop. Look at the modifications I did:
//populate the new array with the unique values
int counter = 0;
for (int i = 0; i < a1.length; i++) {
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
result[counter] = a1[i];
counter++;
}
}
}
The way I would do it
Now, here is how I would create a method like this without the need to check for the duplicates more than once. Look below:
public static int[] removeDups(int[] a1, int[] a2) {
int[] result = null;
int size = 0;
OUTERMOST: for(int e1: a1) {
for(int e2: a2) {
if(e1 == e2)
continue OUTERMOST;
}
int[] temp = new int[++size];
if(result != null) {
for(int i = 0; i < result.length; i++) {
temp[i] = result[i];
}
}
temp[temp.length - 1] = e1;
result = temp;
}
return result;
}
Instead of creating the result array with a fixed size, it creates a new array with the appropriate size everytime a new duplicate is found. Note that it returns null if a1 is equal a2.
You can make another method to see if an element is contained in a list :
public static boolean contains(int element, int array[]) {
for (int iterator : array) {
if (element == iterator) {
return true;
}
}
return false;
}
Your main method will iterate each element and check if it is contained in the second:
int[] uniqueElements = new int[a1.length];
int index = 0;
for (int it : a1) {
if (!contains(it, a2)) {
uniqueElements[index] = it;
index++;
}
}

Compressing array values into another array

I came across this problem called compress. The objective is to take an array, remove any repeated values and return a new array.
I know this would be very easy with ArrayLists, but I want to do it without them.
So far, I've just written a loop to determine the number of unique values so I can construct a new array of the appropriate length. How can I then get the unique values into the new array?
public static int[] compress(int[] array){
int length = 0;
boolean contains = false;
for (int i = 0; i < array.length; i++){
contains = false;
for (int j = 0; j < i; j++){
if (a[i] == a[j]){
contains = true;
j = i;
} else {
contains = false;
}
}
if (!contains){
length++;
}
}
int[] uniqueArray = new int[length];
}
Not Tested but I think this should do the trick.
public static int[] copyArray(int [] num){
int x = 0;
int numDuplicate = 0;
int[] copy = new int[num.length]; // we use this to copy the non duplicates
HashMap<Integer, Integer> count = new HashMap<>(); //hashmap to check duplicates
for(int i = 0; i < num.length; i++){
if(count.containsKey(num[i])){
count.put(num[i], count.get(num[i])+1);
numDuplicate++; // keep track of duplicates
}else{
count.put(num[i], 1); // first occurence
copy[x] = num[i]; // copy unique values, empty values will be at end
x++;
}
}
// return only what is needed
int newSize = num.length - numDuplicate;
int[] copyNum = new int[newSize];
for(int i = 0; i < copyNum.length; i++){
copyNum[i] = copy[i];
}
return copyNum;
}
public static void main(String[] args) {
// sample elements
int[] nums = new int[20];
for(int i = 0; i < nums.length; i++){
nums[i] = (int)(Math.random() * 20);
}
System.out.println(Arrays.toString(nums));
System.out.println(Arrays.toString(copyArray(nums)));
}

Splitting an array at multiple points using an index point

I have come across many examples to split the given array or array list into two arrays or multiple arrays using an index point. I tried them and they are working perfectly. My question is, is it possible to split the array into multiple arrays of varying chunk size given the index point?
For example:
array[] = {10,1,2,3,10,4,5,10,6,7,10,8,10};
index_value = 10;
Then the output should be four arrays such as:
arr1[] = {1,2,3}
arr2[] = {4,5}
arr3[] = {6,7}
arr4[] = {8}
I was able to split them and display the results when the given array is static with no changes. But implementing the same for an array with random numbers and random size was hard. I need to store the split values in many sub arrays and not just printing the values.
For this solution, the index_value does not have to be at the start or end of the array:
int[] arr = new int[]{10,10,1,10,1,2,3,10,4,5,10,6,7,10,8,10,9,8,7,6,5,4,3,10,1,2,3,4,5,6,7,10,5,4,10,10};
int index_value = 10;
/** walk through the array and create the arraylist of arraylists */
ArrayList<ArrayList<Integer>> al = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> currAl = null;
for (int i=0; i < arr.length; i++) {
if (arr[i] == index_value) {
if (currAl != null && currAl.size() > 0)
al.add(currAl);
currAl = new ArrayList<Integer>();
} else {
if (currAl == null)
currAl = new ArrayList<Integer>();
currAl.add(arr[i]);
}
}
if (arr[arr.length-1]!= index_value && currAl.size() > 0) {
al.add(currAl);
}
/** print out the arraylist of arraylists */
for (int i=0; i < al.size(); i++) {
currAl = al.get(i);
for (int j=0; j < currAl.size(); j++) {
System.out.print(currAl.get(j) + " ");
}
System.out.println();
}
You can build your arrays by using the ArrayList class to fill in your values
array[] = {10,1,2,3,10,4,5,10,6,7,10,8,10};
index_value = 10;
ArrayList<ArrayList<int>> allLists = new ArrayList<ArrayList<int>>();
ArrayList<int> currentList;
for (int i = 0;i < array.length;i++)
{
//in case your array doesn't contain the index_value at index 0
//check for the null case
if (array[i] == index_value || currentList == null)
{
currentList = new ArrayList<int>();
allLists.add(currentList);
}
else
{
currentList.add(array[i]);
}
}
if (allLists.size() > 0 && allLists.get(allLists.size() - 1).size() == 0)
{
allLists.remove(allLists.size() - 1);
}
What you should have is an ArrayList that contains ArrayLists that contain the numbers you are interested in. If the index_value is repeated twice in a row, however, you will end up with empty lists (which can be removed later). This includes the final list, which I automatically remove if it is empty (since your example lists the index_value as being at both the start and the end.
If you would like the output to be in arrays, you can just call .toArray() on the ArrayList
You might try the following strategy: look for your marker boundaries, form an array from each segment as encountered, and put result in a Vector (for example).
package com.splitter;
import java.util.Vector;
public class Splitter {
/**
* #param args
*/
public static void main(String[] args) {
int[] array = {10, 1,2,3,10,4,5,10,6,7,10,8,10};
Vector <int[]> result;
result = split(array,10);
for (int i = 0; i < result.size(); i++) {
int[] split = result.get(i);
System.out.println("Array " + i);
for (int j=0; j<split.length; j++) {
System.out.println(split[j]);
}
}
}
private static Vector<int[]> split(int[] array, int value) {
Vector<int[]> result = new Vector<int[]>();
int loc = 0;
int start = 0;
boolean isInside = false;
while (loc < array.length) {
if (array[loc] == value) {
if (isInside) { // make array from start to here
// make an array from start+1 to loc-1
System.out.println(" .." + start + " " + loc + " v=" + array[loc] );
int[] split = new int[loc - start - 1];
for (int i = 0; i < split.length; i++) {
split[i] = array[start+1+i];
}
result.add(split);
isInside = true;
}
start = loc;
isInside = true;
}
loc++;
}
return result;
}
}
I tried in NetBeans, debug, and works well.
The values will be stored like in a ArrayList with more ArrayLists inside, like this:
arrayOfIntList.get(0) = > 1,2,3
arrayOfIntList.get(0).get(0) -> 1
arrayOfIntList.get(0).get(1) -> 2
arrayOfIntList.get(0).get(2) -> 3
arrayOfIntList.get(1) = > 4,5
arrayOfIntList.get(1).get(0) -> 4
arrayOfIntList.get(1).get(1) -> 5
arrayOfIntList.get(2) = > 6,7
arrayOfIntList.get(2).get(0) -> 6
arrayOfIntList.get(2).get(1) -> 7
arrayOfIntList.get(3) = > 8
arrayOfIntList.get(3).get(0) -> 8
import java.util.ArrayList;
public class Javaprueba {
public static void main(String[] args) {
int[] myarray = {10,1,2,3,10,4,5,10,6,7,10,8,10};
int splitterInt = 10;
int j = 0;
int k = 0;
ArrayList<Integer> tempArray = new ArrayList<Integer>();
ArrayList<ArrayList<Integer>> arrayOfIntList = new ArrayList<ArrayList<Integer>>();
for(int i=0; i<myarray.length; i++){
if(myarray[i] != splitterInt){
tempArray.add(j, myarray[i]);
j++;
}else{
if(tempArray.size() > 0){
arrayOfIntList.add(k, tempArray);
k++;
tempArray = new ArrayList<Integer>();
j=0;
}
}
if(i == myarray.length-1 && tempArray.size()>0){
arrayOfIntList.add(k, tempArray);
}
}
}
}

Finding multiple modes in an array of integers with 1000 elements

So I need a way to find the mode(s) in an array of 1000 elements, with each element generated randomly using math.Random() from 0-300.
int[] nums = new int[1000];
for(int counter = 0; counter < nums.length; counter++)
nums[counter] = (int)(Math.random()*300);
int maxKey = 0;
int maxCounts = 0;
sortData(array);
int[] counts = new int[301];
for (int i = 0; i < array.length; i++)
{
counts[array[i]]++;
if (maxCounts < counts[array[i]])
{
maxCounts = counts[array[i]];
maxKey = array[i];
}
}
This is my current method, and it gives me the most occurring number, but if it turns out that something else occurred the same amount of times, it only outputs one number and ignore the rest.
WE ARE NOT ALLOWED TO USE ARRAYLIST or HASHMAP (teacher forbade it)
Please help me on how I can modify this code to generate an output of array that contains all the modes in the random array.
Thank you guys!
EDIT:
Thanks to you guys, I got it:
private static String calcMode(int[] array)
{
int[] counts = new int[array.length];
for (int i = 0; i < array.length; i++) {
counts[array[i]]++;
}
int max = counts[0];
for (int counter = 1; counter < counts.length; counter++) {
if (counts[counter] > max) {
max = counts[counter];
}
}
int[] modes = new int[array.length];
int j = 0;
for (int i = 0; i < counts.length; i++) {
if (counts[i] == max)
modes[j++] = array[i];
}
toString(modes);
return "";
}
public static void toString(int[] array)
{
System.out.print("{");
for(int element: array)
{
if(element > 0)
System.out.print(element + " ");
}
System.out.print("}");
}
Look at this, not full tested. But I think it implements what #ajb said:
private static int[] computeModes(int[] array)
{
int[] counts = new int[array.length];
for (int i = 0; i < array.length; i++) {
counts[array[i]]++;
}
int max = counts[0];
for (int counter = 1; counter < counts.length; counter++) {
if (counts[counter] > max) {
max = counts[counter];
}
}
int[] modes = new int[array.length];
int j = 0;
for (int i = 0; i < counts.length; i++) {
if (counts[i] == max)
modes[j++] = array[i];
}
return modes;
}
This will return an array int[] with the modes. It will contain a lot of 0s, because the result array (modes[]) has to be initialized with the same length of the array passed. Since it is possible that every element appears just one time.
When calling it at the main method:
public static void main(String args[])
{
int[] nums = new int[300];
for (int counter = 0; counter < nums.length; counter++)
nums[counter] = (int) (Math.random() * 300);
int[] modes = computeModes(nums);
for (int i : modes)
if (i != 0) // Discard 0's
System.out.println(i);
}
Your first approach is promising, you can expand it as follows:
for (int i = 0; i < array.length; i++)
{
counts[array[i]]++;
if (maxCounts < counts[array[i]])
{
maxCounts = counts[array[i]];
maxKey = array[i];
}
}
// Now counts holds the number of occurrences of any number x in counts[x]
// We want to find all modes: all x such that counts[x] == maxCounts
// First, we have to determine how many modes there are
int nModes = 0;
for (int i = 0; i < counts.length; i++)
{
// increase nModes if counts[i] == maxCounts
}
// Now we can create an array that has an entry for every mode:
int[] result = new int[nModes];
// And then fill it with all modes, e.g:
int modeCounter = 0;
for (int i = 0; i < counts.length; i++)
{
// if this is a mode, set result[modeCounter] = i and increase modeCounter
}
return result;
THIS USES AN ARRAYLIST but I thought I should answer this question anyways so that maybe you can use my thought process and remove the ArrayList usage yourself. That, and this could help another viewer.
Here's something that I came up with. I don't really have an explanation for it, but I might as well share my progress:
Method to take in an int array, and return that array with no duplicates ints:
public static int[] noDups(int[] myArray)
{
// create an Integer list for adding the unique numbers to
List<Integer> list = new ArrayList<Integer>();
list.add(myArray[0]); // first number in array will always be first
// number in list (loop starts at second number)
for (int i = 1; i < myArray.length; i++)
{
// if number in array after current number in array is different
if (myArray[i] != myArray[i - 1])
list.add(myArray[i]); // add it to the list
}
int[] returnArr = new int[list.size()]; // create the final return array
int count = 0;
for (int x : list) // for every Integer in the list of unique numbers
{
returnArr[count] = list.get(count); // add the list value to the array
count++; // move to the next element in the list and array
}
return returnArr; // return the ordered, unique array
}
Method to find the mode:
public static String findMode(int[] intSet)
{
Arrays.sort(intSet); // needs to be sorted
int[] noDupSet = noDups(intSet);
int[] modePositions = new int[noDupSet.length];
String modes = "modes: no modes."; boolean isMode = false;
int pos = 0;
for (int i = 0; i < intSet.length-1; i++)
{
if (intSet[i] != intSet[i + 1]) {
modePositions[pos]++;
pos++;
}
else {
modePositions[pos]++;
}
}
modePositions[pos]++;
for (int modeNum = 0; modeNum < modePositions.length; modeNum++)
{
if (modePositions[modeNum] > 1 && modePositions[modeNum] != intSet.length)
isMode = true;
}
List<Integer> MODES = new ArrayList<Integer>();
int maxModePos = 0;
if (isMode) {
for (int i = 0; i< modePositions.length;i++)
{
if (modePositions[maxModePos] < modePositions[i]) {
maxModePos = i;
}
}
MODES.add(maxModePos);
for (int i = 0; i < modePositions.length;i++)
{
if (modePositions[i] == modePositions[maxModePos] && i != maxModePos)
MODES.add(i);
}
// THIS LIMITS THERE TO BE ONLY TWO MODES
// TAKE THIS IF STATEMENT OUT IF YOU WANT MORE
if (MODES.size() > 2) {
modes = "modes: no modes.";
}
else {
modes = "mode(s): ";
for (int m : MODES)
{
modes += noDupSet[m] + ", ";
}
}
}
return modes.substring(0,modes.length() - 2);
}
Testing the methods:
public static void main(String args[])
{
int[] set = {4, 4, 5, 4, 3, 3, 3};
int[] set2 = {4, 4, 5, 4, 3, 3};
System.out.println(findMode(set)); // mode(s): 3, 4
System.out.println(findMode(set2)); // mode(s): 4
}
There is a logic error in the last part of constructing the modes array. The original code reads modes[j++] = array[i];. Instead, it should be modes[j++] = i. In other words, we need to add that number to the modes whose occurrence count is equal to the maximum occurrence count

Categories

Resources