max value from arraylist part? - java

i have some int values stored in ArrayList1 (imagine a table with one column). I need to create another ArrayList2 (second column), which will have values, that are the max values of a range in ArrayList1, for example last 3 values. for example:
1 null
2 null
1 2
3 3
2 3
1 3
So the secondt column - ArrayList2, will contain for each row max value of the last 3 corresponding rows in ArrayList1. (same as in xls, B3=MAX(A1:A3)...).
I can do it by creating for each row with a loop that goes and finds out max value, or i can loop and create subArrayList and use collections.max, but both these solutions require a loop for every row, which isn't very practical, isnt there a simpler way? something like arrayList.max(1,3) to get the number straight away?

You can do something like the code I show below. You iterate the first array, calculating the maximum and updating the second array accordingly. Note that you need an extra array to store the intervals.
private void m1(List<Integer> array1, List<Integer> array2, int range) {
Integer[] rangeArray = new Integer[range];
//Iterate first array
for(int i = 0; i < array1.size(); i++) {
Integer x = array1.get(i);
rangeArray[i%range] = x;
//Update second array
if(i < range - 1) {
array2.add(null);
}
else {
int max = Collections.max(Arrays.asList(rangeArray));
array2.add(max);
}
}
}

Using Collections.max
int startFrom = 2; // configurable number
List<Integer> intList = Arrays.asList(1,2,1,3,2,1,4);
List<Integer> sortedList = new ArrayList<>();
for (int i = 0; i < intList.size(); i++) {
if(i < startFrom){
sortedList.add(null);
continue;
}
ArrayList<Integer> list = new ArrayList<Integer>(intList.subList(i -startFrom, i+1));
sortedList.add(Collections.max(list));
}
System.out.println(sortedList);
Output is :[null, null, 2, 3, 3, 3, 4]

Ok. So your size of list to compare can vary , in that case build an array list out of the numbers to compare say List<?> list = Arrays.asList( numbersToCompare );
then Collections.max( list ), the list should contain objects that can be compared in other words needs to be comparable. ( If not write your own comparator )

Related

Creating a custom sort for an array of integers?

Right, so I have a 2 part sorting algorithm. It's all based on an array of 14 random integers. For example:
int[] a = {9,2,4,8,9,4,3,2,8,1,2,7,2,5};
Now, the first thing I'm trying to figure out how to do is to count how many a certain number exists in the original array. So, we know that 1 exists once, and 2 exists four times in the original array. But as easy as it is to visually see this, what if we don't have access to the original array. So I need to craft a method that will count how many of each number 1-9 exists and put this in a new array called count. So that index 0 in count would represent the integer 1 and would have a value of 1. Index 1 will represent the integer 2 and have a value of 4. And so on and so forth. Here is what I've got so far but I'm stuck. Sorting is pretty challenging for me.
public static void main(String[] args)
{
// int[] countFinal = {1,4,1,2,1,0,1,2,2}; // The number of times a number 1-9 appears in a[].
// int[] sortedFinal = {1,2,2,2,2,3,4,4,5,7,8,8,9,9}; // What we need as a final product.
int[] a = {9,2,4,8,9,4,3,2,8,1,2,7,2,5};
//int[] count = {};
int[] sorted = {};
countHowMany(a, 1);
countHowMany(a, 2);
countHowMany(a, 3);
countHowMany(a, 4);
countHowMany(a, 5);
countHowMany(a, 6);
countHowMany(a, 7);
countHowMany(a, 8);
countHowMany(a, 9);
}
public static int countHowMany(int[] array, int value)
{
// Gathering a count for how many times a number 1-9 exists and adding it to count[];
int howManyCount = 0;
for (int i = 0; i < array.length; i++)
{
if (array[i] == value)
{
howManyCount++;
}
}
System.out.println(howManyCount);
count = new int[9];
count[howManyCount];
System.out.println(Arrays.toString(count); // Testing the input
return howManyCount;
}
It appears to count the number of times an item in the array exists properly. Now I just gotta figure out how I can add that value into a new array count[] and do it for each countHowMany(). This is the part I'm stuck on.
Once I have figured out count[] I can use it to create sorted[]. Now what sorted is supposed to do is take the data from the original array and count[] and create a new array that sorts it in ascending order and allows duplicates. So, since 1 occurs once and 2 occurs four times, the new array would be sorted[] = {1, 2, 2, 2, 2, ...}
It's a relatively small program and a small amount of integers, so it's ok that I create array's as necessary. The key being that I'm limited to using arrays and cannot use say ArrayLists for this.
You don't need to count each value individually. You can just iterate through the entire array and increment your counters for each element as you encounter it.
int counts = new int[20]; // Choose a value that's bigger than anything in your array.
int[] a = {9,2,4,8,9,4,3,2,8,1,2,7,2,5};
for (int value : a) {
counts[value]++;
}
If you don't know what the largest value in your array is likely to be, you're better to use either a Map to store the counts, or some kind of List that you increase the size of as needed.
You're better off just going through the array once and incrementing a counter for each value that might appear:
int counts[] = new int[10];
for (int n: array)
counts[n]++;
That's enough to put the count for each n in counts[n]. You can then read the values out of your count[] array.
You might not have come across this syntax for a for loop over an array, by the way. It's equivalent to
int counts[] = new int[10];
for (int i=0; i<array.length; i++) {
int n = array[i];
counts[n]++;
}
but it's less verbose.
Your method may as well be void, since you're not doing anything with the returned values of your countHowMany function. This will accomplish what you want:
public static void main(String[] args)
{
int[] a = {9,2,4,8,9,4,3,2,8,1,2,7,2,5};
//count the instances of each number in the array
int[] count = new int[9];
for(int i = 0; i < count.length; i++)
count[i] = countHowMany(a, i+1);
//put the values in the sorted array
int[] sorted = new int[a.length];
int position = 0; // stores the place in the array to put the new digit
for(int digit = 0; digit < 9; digit++)
{
for(int inst = 0; inst < count[digit]; inst++)
{
sorted[position] = digit + 1;
position++;
}
}
System.out.println(Arrays.toString(sorted));
}
The issue with your code is that you were trying to create the count array in each call of the countHowMany method, but this array is destroyed once the method finishes. The method calls should just return the counts, and then those returns should be put into the count array from outside the method. Note, however, that there are other ways to count the number of instances of each value, as noted by other answers.

Get the missing digits of an array

I have an array with digits and that array is not sorted. The user is able to delete numbers from the array. But the user should be able to add the digit later.
Basically I want to write in a database the id. The user is able to remove rows but if he add a row the id should be a missing digit from a deleted row.
At the moment I solve it like that:
for (Object[] object : data) {
if ((int) object[1] > id) {
id = (int) object[1];
}
}
But with that I only get the largest number and not the missing number. How I am able to get a missing number?
Example:
4, 2, 3, 1 the user deletes row 2 and row 4 so I have
3, 1 now I want to calculate or with if statements whatever to get the 2 and, if the user add a another row the, 4 back.
Keep in mind that the user could close the program, so it is not possible to save the numbers in a other array!
Thank you for help
From your example, sum the numbers from the beginning to the end, 1+2+3+4 = 10 and subtract the sum of the numbers you have, 1+2+4 = 7
So 10 - 7 = 3 (the missing number)
----------------------------------------------------EDIT ----------------
how about this?
public class SandBox7 {
public static void main(String[] args) {
Integer[] array = new Integer[] { 1, 4, 9 };
SandBox7 s = new SandBox7();
List<Integer> mis = s.getMissingNumbers(array);
}
public List<Integer> getMissingNumbers(Integer[] in) {
int max = getMaximum(in);
// System.out.println(max);
List<Integer> numbers = Arrays.asList(in);
ArrayList<Integer> missing = new ArrayList<>();
for (int i = 1; i < max; i++) {
if (!numbers.contains(i)) {
missing.add(i);
}
}
return missing;
}
private int getMaximum(Integer[] in) {
int tmp = -1;
for (int i = 0; i < in.length; i++) {
if (tmp < in[i])
tmp = in[i];
}
return tmp;
}
}
Look at below code..might be helpful
int data[]={1,2,4};
int i=1;
for(Object object : data){
if((Integer)object!=i++)
break;
}
System.out.println(i-1);//This will print 3.
One approach could be maintaining a parallel array which will contain the deleted number.
Object[] data = ...;
Object[] delData = ...;
So every time you insert/add a new number you need to check that number exists in parallel array or not.
You have some possibilities, and it is a design problem you have to decide yourself. Just some alternatives:
Best: renumber IDs on deletion, but needs meta information on referencing foreign keys.
If the data is ordered by ID.
The numbers of deletions when not renumbered:
int deletions = data.length
- (data.length == 0 ? 0 : data[data.length - 1][1]);
With a binary search, you can find a deleted hole (shifted number).
Unordered. Keep the number of deletions maybe.
Keep an unbounded BitSet of data.length bits.
Or alternatively a Set<Integer> with deletions. And renumber when the set becomes too large. (A set of ranges from-ID upto to-ID would be better.)
If you sort the id's in a temporary storage so it would be simple to find the first missing number;
int arr[] = {0,1,2,5}; //think you've the sorted array now
int missing = arr.length; //would have the last id+1 if there is no missing id
for (int i = 0; i < arr.length; i++) {
if (i != arr[i]) {
missing = i;
break;
}
}
System.out.println(missing); //3 will be printed.

Java - Compare 2 int Arrays and judge them based on their values [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have a set of 2 int Arrays containing the same amount of numbers
for example
int[] array1 = {1,3,5,5,2}
int[] array2 = {5,3,4,4,4}
I need to compare them based on 2 criteria
How many elements have the same value on the same index
How many elements have the same value on a different index
And return an array of integers presenting the values
I have a few examples so you can understand better:
int[] array0 = {1,3,5,5,2};
int[] array1 = {5,3,4,4,4};
int[] array2 = {5,3,4,4,5};
int[] array3 = {2,3,2,2,4};
int[] array4 = {5,5,2,1,3};
int[] array5 = {3,1,5,5,2};
int[] array6 = {1,3,5,5,2};
compare(array0,array1); //this would return 1,1
compare(array0,array2); //this would return 1,2
compare(array0,array3); //this would return 1,1
compare(array0,array4); //this would return 0,5
compare(array0,array5); //this would return 3,2
compare(array0,array6); //this would return 5,0
For the first number it's easy, I just need to check if element on index i of array1 is the same as in array2.
I have problems producing the second number because the lowest number from one of the arrays should be taken.
If I just look if element of array1 is somewhere in array2 it produces a wrong result in some cases.
if you look at
int[] array1 = {1,3,5,5,2}
and
int[] array3 = {2,3,2,2,4};
and check if array1 has the same contents as array3 on an index, it would return 3 numbers are equal but on a different spot which is wrong because it should judge from the lowest number and the result there should be 1.
If I switch it around to compare if array3 has the same contents as array1 on some index it works for this case but not for others.
Any ideas on how to approach this, I'm pretty clueless?
Clone the two input integer arrays.
Check and see if the elements have the same value on the same index.
If so, add 1 to the same index counter and change the values in the input integer arrays to -1 (or a number less than the smallest valid value).
Check and see if the elements have the same value using a nested for loop. In other words, check the first element of the first integer array with all the elements of the second integer array. Skip the element that has the same index in both arrays, and skip elements that are less than the smallest valid value.
If so, add 1 to the different index counter and change the values in the input integer arrays to -1 (or a number less than the smallest valid value).
This should do the trick:
public void compare(int[] arrayA, int[] arrayB) {
int sameIndex = 0;
int diffIndex = 0;
//Made two new empty arrays to save the status of each element in the corresponding array, whether it has been checked our not, if not, it'd be null.
String[] arrayAstatus = new String[arrayA.length];
String[] arrayBstatus = new String[arrayB.length];
for (int i = 0; i < arrayA.length; i++) {
if (arrayA[i] == arrayB[i] || arrayAstatus[i] != null) {
sameIndex++;
continue;
}
for (int a = 0; a < arrayB.length; a++) {
if (a == i || arrayBstatus[a] != null) {
continue;
}
if (arrayA[i] == arrayB[a]) {
arrayAstatus[i] = "checked";
arrayBstatus[a] = "checked";
diffIndex++;
break;
}
}
}
System.out.println(sameIndex + ", " + diffIndex);
}
Maybe for the second condition, you could try removing the numbers from the arrays and breaking out of the loop once they are found to have a match. You could have temporary arrays that you set to the values of the original arrays. Then check the value of array1[0] against all the values in array3. When a match is found, remove the number from both arrays and check array1[1] against all the values in array3.
So when you check array1[4] against array3[0], you will get a match. Then you will remove both numbers and break out of the loop. There are no more numbers to check in array1, so the result would be 1.
I think this would clear up the issue of counting the same value twice.
First of all, this sounds like a really bad idea. Don't return an array where each index means something different and cryptic. Make two methods: compareSameIndex(array, array) and compareDifferentIndex(array, array).
To the actual implementation of how these, you could check every index in the first array to see if they appear anywhere in the second array and call that just compare(). Then compareDifferentIndex() becomes compare()-compareSameIndex(). For instance:
public int compare (int[] array0, int[] array1) {
int matches = 0;
List<Integer> list1 = Arrays.asList(array1);
for (int curInt : array0) {
if (list1.contains(curInt)) {
matches++;
}
}
return matches;
}
public int compareSameIndex(int[] array0, int[] array1) {
int matches = 0;
for (int i=0; i < array0.length; i++) {
if (array0[i] == array1[i]) {
matches++
}
}
return matches;
}
public int compareDifferentIndex(int[] array0, int[] array1) {
return compare(array0, array1) - compareSameIndex(array0, array1);
}
The requirements seem a little vague about what happens when the same number appears twice but you could build that logic into compare() to accommodate. Also you could optimize this for very large arrays where you don't check the same number twice, but this would be the general approach I would take.
You could have a Set with numbers already visited. You would something like: (not testing if this code runs, it's just to give you an idea)
public int[] compare(int[] first, int[] second) {
Set<Integer> numbersFoundInFirstArray = new LinkedHashSet<Integer>();
Set<Integer> numbersFoundInSecondArray = new LinkedHashSet<Integer>();
int inSameIndex = 0;
int inDifferentIndex = 0;
for (int i; i < first.length; i++) {
if (first[i] == second[i]) {
inSameIndex++;
}
if (numbersFoundInFirstArray.contains(second[i])) {
inDifferentIndex++;
}
if (numbersFoundInSecondArray.contains(first[i])) {
inDifferentIndex++;
}
numbersFoundInFirstArray.add(first[i]);
numbersFoundInSecondArray.add(second[i]);
}
return new int[] {inSameIndex, inDifferentIndex};
}
The contains comparison in set has O(1) if I remenber well. The property of Set is that you will only have one element of a certain type. So, if you add 1 two times, it will have only one reference of 1. This way, you will only test if the current number was already found in the other array :)
Checking arguments is just good practice.
There are probably some minor optimizations that can be done here, but a Hash will let you store positions you've already visited so as to not count them more then once.
private int[] compare(int[] arr1, int[] arr2){
int same_index = 0;
Hashtable differences = new Hashtable();
int diff_count = 0;
if (arr1.length != arr2.length){
throw new IllegalArgumentException("Array Size is not identical.");
} else {
for(int count = 0; count < arr1.length; count++){
if (arr1[count] == arr2[count]{
same_index++;
differences.put(count, null);
} else {
for (int count2 = 0; count2 < arr1.length; count2++){
if(!differences.containsKey(count2) && arr1[count] == arr2[count2]){
differences.put(count2, null);
diff_count++;
}
}
}
}
}
int[] returnArray = new int[2];
returnArray[0] = same_count;
returnArray[1] = diff_count;
return (returnArray);
}
You need to transpose all the arrays into a tree-like structure which will basically index all the unique values in all arrays and store pointers to their positions in the array and which array. The basic blueprint structure for that tree would be:
uniqElemVal->arrayIndx->arrayID = true
Where uniqElemVal would be 1,3,5,2 for 1,3,5,5,2, 2,3,4 for 2,3,2,2,4, etc, all unionized
arrayIndx would be for 1 in the 1st array 0, for 5 would be 2 and 3 etc.
array ID is something arbitrary that lets you key each array, e.g. 1 for the first, 2 for the second etc.
So in this case:
#1st array
1->0->1
3->1->1
5->2->1
5->3->1
2->4->1
#2nd array
2->0->2
3->1->2
3->2->2
2->3->2
2->4->2
4->5->2
Then when you traverse this tree, whenever you have a 2nd level node with more than 1 leafs, that means that there is a match for that particular element value in the particular position across multiple arrays.
I would personally define this tree as
HashMap<Integer, HashMap<Integer, ArrayList<Integer>>>
So whenever you have a leaf array list with >1 elements, that means you have a match

How do you pull an integer from a specific location in a bidimensional arraylist?

If I have an ArrayList of ArrayLists say "biglist".
[[1,2,3],[4,3,2],[5,1,2],[6,4,7],[7,1,2]]
How could I tally all of the 1's in the first row (so 1 4 5 6 7, total of one 1), and the same for the second etc?
I lost on this so any help or guidance would be appreciated.
ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
//...add your integer to the list
ArrayList<Integer> newList = new ArrayList<Integer>();
for(int i = 0; i < list.size(); i++)
{
if(i == 2 || i == 3) //for instance if you want to exclude certain sublists in your list
continue;
ArrayList<Integer> ints = list.get(i);
if(ints.size() > 0)
newList.add(ints.get(0 /* 0 or whatever part of inner list you want */));
}
Have you tried something like:
public ArrayList<ArrayList<Integer>> getElements(ArrayList<ArrayList<Integer>> bigList, int columnIndex){
ArrayList<Integer> resultList = new ArrayList<Integer>();
for ( ArrayList<Integer> al : bigList ){
resultList.add(al.get(columnIndex));
}
return resultList;
}
NOTE: I say columnIndex because I see your bigList as a matrix.
How could I tally all of the 1's in the first row (so 1 4 5 6 7, total of one 1), and the same for the second etc?
You can count the number of times you see a particular number in a row using something like:
int intWeAreLookingFor = 1;
int rowNumber=0;
for(ArrayList list: biglist){
int numOfHits=0;
rowNumber++;
for(Integer i: list){
if(i.equals(intWeAreLookingFor)){
numOfHits++;
}
}
System.out.printLine("The number '"+intWeAreLookingFor
+"' was counted "+numOfHits+" times in row "+rowNumber+".");
}
For your sample array [[1,2,3],[4,3,2],[5,1,2],[6,4,7],[7,1,2]], this would print out:
The number '1' was counted 1 times in row 1.
The number '1' was counted 0 times in row 2.
The number '1' was counted 1 times in row 3.
The number '1' was counted 0 times in row 4.
The number '1' was counted 1 times in row 5.

Check for recurring numbers in a int[] Java

I want to be able to tell if a any number in an int[] appears 3 or more times? How can I do this?
Would be awesome to have method
boolean hasTriples(int[] numbers) {
//some code
}
Create a Map<Integer, Integer>, and let integer n map to the number of occurrences of n.
Loop through the array to populate the map, then loop through the keys in the map to check which keys map to a value >= 3.
Here's some code to get you started:
int[] arr = { 1, 3, 2, 3, 3, 4, 2, 2 };
Map<Integer, Integer> counts = new HashMap<Integer, Integer>();
// Count occurrencies
for (int i : arr) {
if (!counts.containsKey(i))
counts.put(i, 0);
counts.put(i, 1 + counts.get(i));
}
// Print how many times each number occurs in arr.
for (int i : counts.keySet())
System.out.printf("i: %d, count: %d%n", i, counts.get(i));
public boolean anyRepeatThreeTimes( int [] array ) {
Map<Integer, Integer > map = new HashMap<Integer, Integer>();
for ( int index = 0; index < array.length; index++ ) {
Integer total = map.get(array[ index ]);
int count;
if ( total == null ) {
count = 1;
}
else {
count = total + 1;
if ( count >= 3 ) {
return true;
}
}
map.put( array[ index ], count );
}
return false;
}
Here's what's going on:
You pass in the array of ints.
You set up a map of array values to a count of the value.
You walk the array. For each integer in the array:
a. you retrieve the current count for that array value
b. if no value exists, then start with a value of 1
c. if a value does exist in the map for the given value, add one to it
d. if the value retrieved from the map + 1 exceeds your limit of 3, then you have demonstrated that there is a value in the array that is repeated at least three times.
if you make it to the end of the loop without ever returning true, then return false instead, because no value is repeated 3 times.
Here is a way to do it without using any extra classes such as the Map class. It might be slower but hopefully is easier to understand.
public boolean hasTriples(int[] list) {
for (int i = 0; i < list.length; i++){
int duplicates = 0;
for (int j = i+1; j < list.length; j++){
if (list[i] == list[j]) {
duplicates++;
if (duplicates >= 3) return true;
}
}
}
return false;
}
Here is what this code is doing. The outer for loop is running through the list to make sure that every value is checked for duplicates. The inner loops runs through the remeinder of the list to check how many duplicate values there are. If three or more duplicates are found the function will return true and not process the rest of the list. If the outer for loop finishes without the method returning true false is returned as there must not be any three duplicates.
Hope this helps!

Categories