how to find latest element added or deleted in dynamic array - java

I am getting an input array in loop which contains numbers in sorted order. on Every iteration the input array will either be added or be deleted with any one number (no duplicates in input array). Example
1st iteration: Input Array [3,4,8,19]
2nd iteration: Input Array [3,4,5,8,19]
Output: 5 added
3rd iteration: Input Array [3,4,5,8,19,40]
Output: 40 added
4th iteration: Input Array [3,5,8,19,40]
Output: 4 deleted
5th iteration: Input Array [1,3,5,8,19,40]
Output: 1 added
Note: I have a solution where I can take a map or different array and copy the input array in new array then from next iteration onward I'm going to iterate input array and compare the input array's elements with new array, the one not present in new array is the one added; and the one present in new array but not present in input array is the one deleted. I am looking for a better approach with most optimized logic in terms of space and time.

Given below is one of the simplest ways:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int first[] = { 3, 4, 8, 19 };
int second[] = { 3, 4, 5, 8, 19 };
int diff = Arrays.stream(second).sum() - Arrays.stream(first).sum();
System.out.println(Math.abs(diff) + (diff > 0 ? " added." : diff < 0 ? " deleted." : ""));
}
}
Output:
5 added.
Demo:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[][] testArrs = {
{ 3, 4, 8, 19 },
{ 3, 4, 5, 8, 19 },
{ 3, 4, 5, 8, 19, 40 },
{ 3, 5, 8, 19, 40 },
{ 1, 3, 5, 8, 19, 40 } };
int i, diff = 0, lastSum = Arrays.stream(testArrs[0]).sum(), currentSum;
for (i = 1; i < testArrs.length; i++) {
currentSum = Arrays.stream(testArrs[i]).sum();
diff = currentSum - lastSum;
System.out.println(Math.abs(diff) + (diff > 0 ? " added." : diff < 0 ? " deleted." : ""));
lastSum = currentSum;
}
}
}
Output:
5 added.
40 added.
4 deleted.
1 added.

If the array is always sorted and the input only changes in one place, then if you have access to both the old and the new array at each iteration, an efficient algorithm could search for the first different elememt between the arrays in O(log n) time with binary search. If mid points to different elements, look in the left half; otherwise, in the right.

Related

I have an infinite for loop but I cant find which part of my code is causing it

I am trying to solve the Josephus problem with an ArrayList and for loops. I have created an infinite for loop within my circle.size for loop but I cant deduce which part of my code is causing it to happen.
public class project1 {
public static int Josephus (int n, int k){
ArrayList<Integer> circle = new ArrayList<Integer>();
for (int p = 1; p <= n; p++) {
circle.add(p);
}
System.out.println("There are " + n + " people in the circle.");
System.out.println(circle);
ArrayList<Integer> kill_order = new ArrayList<Integer>();
for (int index=1; circle.size()!=1; index++){
if (circle.size() > 1){
index = (index + k - 1) % circle.size();
kill_order.add(index);
circle.remove((Integer)index);
System.out.println(kill_order);
} else if (circle.size()==1){
System.out.println("Execution Order: " + kill_order + " ");
System.out.println(kill_order);
index = 1;
}
}
return circle.get(0);
}
public static void main(String[] args) {
System.out.println("You should sit in seat " + Josephus(7, 2) + " if you want to survive!");
}
}
I think that the problem is related to this line of code circle.remove((Integer)index);
if you replace with circle.remove(index) the programs end without any infinite loop.
If you call the method circle.remove((Integer) index) it search an element inside the array with that value, the method circle.remove(index) it remove the element at the specified index.
See the javadoc for additional details remove(int index) remove(Object o)
Every next iteration of your main loop looks like:
index at the beginning of the loop
index after assign new value
circle array
1
2
1, 3, 4, 5, 6, 7
3
4
1, 3, 5, 6, 7
5
1
3, 5, 6, 7
2
3
5, 6, 7
4
2
5, 6, 7 - it cannot remove value 2 and array is not size 1
3
1
5, 6, 7
2
0
5, 6, 7
1
2
5, 6, 7
3
1
5, 6, 7 - cycle starts to repeat
So probably your algorithm is wrong, or you should remove element at index, not by value (circle.remove(index)) - without converting it to Integer

How to find common sequences between two lists in Java

I'm trying to find common sequences between two lists.If we try to find common sequences in lists which has all unique values , i can do it. For example:
list one: [1, 8, 3, 13, 14, 6, 11]
listTwo : [8, 9, 10, 11, 12, 13, 14, 15]
As we can see , the [13,14] sequence is common for two list. My algorithm is , with retainAll function i'm having the common values , and for this example it's [8,11,13,14]. But since the list one has changed by "retainAll" function, i'm creating copy of list one. Then i'm taking positions of these common values from their original lists (list one and list two). After that i'm getting difference of positions for consecutive values. Like:
list1 list2 difList1 difList2
[8] 1 0 -1 (0-1) -1 (0-1)
[11] 6 3 -5 (1-6) -3 (0-3)
[13] 3 5 3 (6-3) -2 (3-5)
[14] 4 6 -1 (3-4) -1 (5-6)
If both difList1 and difLis2 values are shows "-1" that means , that value and the previous one is consecutive and makes sequence.Since [14] meets the condition in this example, the sequence is [13][14].
For this case , my code is:
public static void main(String args[]) {
List<Integer> list1= new ArrayList(Arrays.asList(1, 8, 3, 13, 14, 6, 11));
List<Integer> list2= new ArrayList(Arrays.asList(8, 9, 10, 11, 12, 13, 14, 15));
list1.retainAll(list2);
List<Integer> ori_list1= new ArrayList(Arrays.asList(1, 8, 3, 13, 14, 6, 11));
List<Integer> difList1= new ArrayList<>();
List<Integer> diffList2= new ArrayList<>();
difList1.add(-1); // Since the first element doesn't have any previous element in common elements list,i'm putting -1 on first index.
diffList2.add(-1); // Since the first element doesn't have any previous element in common elements list,i'm putting -1 on first index.
System.out.println(list1); // common elements are [8, 13, 14, 11]
for(int k=1;k<list1.size();k++){ // Let's say k = 2 ..
int index1_1 = ori_list1.indexOf(list1.get(k)); // For index 2, it takes actual index of 14 value -> 4
int index1_2 = ori_list1.indexOf(list1.get(k-1)); // it takes actual index of 13 value -> 3
int diff_list1 = index1_2-index1_1; // 3-4= -1 -> we got -1 .That means they're consecutive.
difList1.add(diff_list1); // And putting the -1 into the diffList1.
int index2_1 = list2.indexOf(list1.get(k)); // doing the same thing for list2.. -> 6
int index2_2 = list2.indexOf(list1.get(k-1)); // doing the same thing for list2.. -> 5
int diff_doc2 = index2_2-index2_1; // 5-6 = -1
diffList2.add(diff_doc2); // put -1 in diffList2
}
for(int y=1;y<difList1.size();y++){
if(difList1.get(y)==-1 && diffList2.get(y)==-1){ // Since they are both -1 for 14 value
System.out.println("The common sequence is:"+list1.get(y-1)+" "+list1.get(y)); // Print them
}
}
}
But I need the solution for the duplicate elements situation. Let's say we have lists like
list one: [1, 8, 3,10, 13,8,10, 14, 6, 11]
listTwo : [8, 9, 10, 11, 12,8,10, 13, 14, 15]
Now we have another common sequence [8,10].In the output , i wanna see both [13,14] and [8,10]. But i only see [13,14]. Because when indexes are calculating for 8 and 10 , the program takes the indexes of first 8 and 10. For list1 , it takes 1st index for 8 value and 3rd index for 10 value. But i need to pass them since i used them already, i need indexes like 5 and 6,not 1 and 3 again.
And i don't know how to find sequences which has more than two values. For example not only [13,14] but also [13,14,15] or more if they are consecutive. I know it's kinda tough question but i need your help.
I am not exactly sure what you are trying to do but if I was doing common sequences I would do it by creating sublists and comparing them:
public static Set<List<Integer>> findCommonSequence(List<Integer> source, List<Integer> target, int startLength) {
Set<List<Integer>> sequences = new LinkedHashSet<>();
// algorithm works in this way:
// we prepare all possible sublists of source list that are at least startLength length
// and then we check every of those sublists against the target list to see if it contains any
// length is from startLength to maxSize, to check all sublists with that length
// ie if startLength is 2 and source is 10, it will be 2 - 10 and thus it will check all sublist sizes
for (int length = startLength; length < source.size(); length++) {
// startIndex will move from 0 to original_list - length, so if length is 2, it will generate sublists
// with indexes 0,1; 1,2; 2,3 ... 8,9
for (int startIndex = 0; startIndex+length < source.size(); startIndex++) {
// creates lightweight sublist that shares the data
List<Integer> sublist = source.subList(startIndex, startIndex+length);
// add all found subsequences into the set
sequences.addAll(findSequenceIn(target, sublist));
}
}
return sequences;
}
// Returns all subsequences that are inside the target list
private static Set<List<Integer>> findSequenceIn(List<Integer> target, List<Integer> sublist) {
Set<List<Integer>> subsequences = new LinkedHashSet<>();
// simply do the same process as in first method but with fixed length to the length of sublist
for (int i=0; i<target.size() - sublist.size(); i++) {
// create another sublist, this time from target (again, share data)
List<Integer> testSublist = target.subList(i, i+sublist.size());
// compare two sublists, if they are equal, that means target list contains sublist from original list
if (testSublist.equals(sublist)) {
// add it to the set
subsequences.add(new ArrayList<>(sublist));
}
}
return subsequences;
}
You can then optimize the algorithm to just do the checks via sending the indexes instead of sublists and do the comparing manually. Complexity of this algorithm should be from O(n3) to O(n4). Might be O(n4) because we do up to n2 sublists and then compare which is n operation against n sublists of list 2, but it might be n3 because comparisons are smaller, no idea mathematically how close it is to n3 or n4.
Of course there is another n with copy of sublist but you can optimize that one out.
handling the int-values as codePoints:
[1] convert list2 to str2
[2] convert list1 to str1 with all int-values on the left stripped, that are not in list2
[3] move str1 over str2 remembering the longest sequence of str1 standing on top of str2
ArrayList<int[]> results = new ArrayList<>();
String str2 = new String(
new int[] { 1, 8, 3, 10, 13, 14, 8, 10, 14, 6, 11 }, 0, 11 ); //[1]
int[] tmp = new int[] { 8, 9, 10, 11, 12, 8, 10, 13, 14, 15 };
int[] arr1 = IntStream.of( tmp ).dropWhile(
c -> str2.indexOf( c ) < 0 ).toArray(); //[2]
String str1 = new String( arr1, 0, arr1.length );
for( int i = str1.length() - 2; i >= 0; i-- ) { //[3]
int[] rslt = new int[0];
for( int j = 0; j < str2.length() - 2; j++ ) {
int[] idx2 = new int[] { j };
rslt = str1.substring( i ).codePoints().takeWhile(
c -> c == (int)str2.charAt( idx2[0]++ ) ).toArray();
if( rslt.length >= 2 ) {
results.add( rslt );
}
}
}
results.forEach(a -> System.out.println( Arrays.toString( a ) ));
gets: [13, 14], [10, 13, 14], [8, 10]

Java program to find 'Lucky' numbers from 0 to n using Lists

I have to write a program that finds all the lucky numbers from 0 to any number n.
Here's what a lucky number is:
Consider the sequence of natural numbers.
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 ………………………………….
Removing every second number produces the sequence
1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23 ………………………….
Removing every third number produces the sequence
1, 3, 7, 9, 13, 15, 19, 21, 25 ………………………….
This process continues indefinitely by removing the fourth, fifth…and so on, till after a fixed number of steps, certain natural numbers remain indefinitely. These are known as Lucky Numbers.
I decided to try using ArrayList for this. But I can't seem to figure this small bit out. I've been trying for days now.
Here's the code:
import java.util.*;
class luckyy
{
public static void main(String args[])
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter n: ");
int i, n, index;
n = scan.nextInt();
ArrayList <Integer> ele = new ArrayList <Integer> (n);
//storing in a list
for(i = 1;i<=n;i++)
{
ele.add(i);
}
System.out.println(ele);
int count = 2;
index = 1;
System.out.println("Size: "+ele.size());
while(count<ele.size())
{
for(i = 0;i<ele.size();i++)
{
int chk = ele.get(i);
if(chk%count == 0)
{
ele.remove(i);
}
}
count++;
}
System.out.print(ele);
}
}
This gives the output:
[1, 5, 7]
When the desired output is:
[1, 3, 7]
So, sorry if this code is so bad that it's offensive haha...
But I would really appreciate any help. I am just starting out as a programmer, and have a lot to learn, and would love any advice. Thanks to anyone who tries to help me!
First of all it seems to me that your assumption of the expected output is not correct. According to the task you described, the out should be something like this:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25] // every 2nd number removed
[1, 3, 7, 9, 13, 15, 19, 21, 25] // every 3rd number removed
[1, 3, 7, 13, 15, 19, 25] // every 4th number removed
[1, 3, 7, 13, 19, 25] // every 5th number removed
[1, 3, 7, 13, 19] // 6th number removed = final output
Beside that, I see two mistakes.
You want to remove "every n-th number", so you don't want to test the values, but their position/index in the list.
Whenever you remove an element from an ArrayList, the index of the following elements and the size of the list is reduced by 1. Means if you start with removing the "2", the next number to remove will be the "5", not the "4" as desired (assuming you are testing the index, not the value). One solution for that would be to test the indexes starting at the end of the list. In that case it wouldn't matter that higher indexes change after removing elements, because you already passed them.
Edit
Answer edited in regard to request of #Kedar Mhaswade to provide some code in order to test how removing elements from the end of the list perfoms.
This is my first approach:
List<Integer> removeBackward(List<Integer> numbers) {
int count, sPos;
count = 2;
while(count<=numbers.size())
{
for(sPos = numbers.size(); sPos >= numbers.size()-count; sPos--)
{
if(0 == sPos%count) {
break;
}
}
for(int pos = sPos; pos > 0; pos=pos-count)
{
numbers.remove(pos-1);
}
count++;
}
return numbers;
}
I did some tests (see below) with the result that it performs quite well for small sets of numbers (< 12000). On larger sets the second approach of #Kedar Mhaswade (maintaining an extra list for the elements to retain) outperforms this approach.
Therefore I tried a second approach:
The idea was, that there is no need to maintain a second list for retained elements when at first step half of the elements will be removed and the number of elements to retain decreases step by step.
So I simply moved the elements to retain to the end of the same list and maintain additional pointers in order to know the range of the retained elements. At the end of the process the final result only needs to be extracted from the end of the list.
List<Integer> retainedAtEnd(List<Integer> numbers) {
int removeX, baseQty, retainedQty, basePos, retainedPos;
removeX = 1;
baseQty = numbers.size();
while(removeX <= baseQty)
{
removeX++;
basePos = numbers.size();
retainedPos = basePos;
retainedQty = 0;
for(int checkPos = baseQty; checkPos >= 1; checkPos--)
{
if(0 != checkPos%removeX)
{
basePos = numbers.size()-baseQty+checkPos;
numbers.set(retainedPos-1, numbers.get(basePos-1));
retainedPos--;
retainedQty++;
}
}
baseQty = retainedQty;
}
return numbers.subList(numbers.size()-baseQty, numbers.size());
// return new ArrayList(numbers.subList(numbers.size()-baseQty, numbers.size()));
}
According to my test unforunately this approach doesn't perform to good on small sets (<12000). It can not compete with the first or #Kedar Mhaswade's second approach, but on larger sets, it outperforms both.
Here is how I tested:
public void test() {
int n = 1000;
long start;
System.out.println("Testing with " + n + " numbers ...");
System.out.println("Test removing elements backwards:");
List<Integer> numbers1 = Stream.iterate(1, k -> k + 1).limit(n).collect(Collectors.toList());
start = System.nanoTime();
List<Integer> out1 = this.removeBackward(numbers1);
System.out.println("Time taken:" + (System.nanoTime() - start));
// System.out.println(out1);
System.out.println("Test maintaining extra list for retained elements:");
List<Integer> numbers2 = Stream.iterate(1, k -> k + 1).limit(n).collect(Collectors.toList());
start = System.nanoTime();
List<Integer> out2 = this.extraRetainedList(numbers2);
System.out.println("Time taken:" + (System.nanoTime() - start));
// System.out.println(out2);
System.out.println("Test collecting retained elements at end of list:");
List<Integer> numbers3 = Stream.iterate(1, k -> k + 1).limit(n).collect(Collectors.toList());
start = System.nanoTime();
List<Integer> out3 = this.retainedAtEnd(numbers3);
System.out.println("Time taken:" + (System.nanoTime() - start));
// System.out.println(out3);
System.out.println("Test maintaining extra list for elements to remove:");
List<Integer> numbers4 = Stream.iterate(1, k -> k + 1).limit(n).collect(Collectors.toList());
start = System.nanoTime();
List<Integer> out4 = this.extraDeletedList(numbers4);
System.out.println("Time taken:" + (System.nanoTime() - start));
// System.out.println(out4);
}
This is a tricky problem! I went about it in a slightly different fashion and used another list to store the deleted elements. This is required because of the data structure that I chose. Since I wanted to use integers only and I was using an ArrayList, every time I remove an element, the list gets immediately adjusted. What we really need to do is mark the element for deletion. There are more than one way to do this, but I chose to maintain another list of deleted elements (since all the elements are unique, it is fine to use this idea).
Here is my first attempt then:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** <p>
* Find the lucky numbers amongst natural numbers from 1 to n.
* Here's how you find Lucky numbers.
* </p>
* Created by kmhaswade on 2/27/16.
*/
public class Lucky {
public static void main(String[] args) {
printLucky1(Integer.valueOf(args[0]));
}
private static void printLucky1(int n) {
List<Integer> numbers = Stream.iterate(1, k -> k + 1).limit(n).collect(Collectors.toList());
System.out.println(numbers);
int delIndex = 1; // index of the element to be removed, we start with 2nd element
while (delIndex < numbers.size()) {
List<Integer> deleted = new ArrayList<>();
for (int i = delIndex; i < numbers.size(); i += (delIndex + 1)) {
deleted.add(numbers.get(i));
}
numbers.removeAll(deleted); // expensive operation!
System.out.println(numbers);
delIndex += 1;
}
System.out.println("number of lucky numbers:" + numbers.size());
System.out.println(numbers);
}
}
This works! But for really long lists, this is very slow, because of the expensive operation: numbers.removeAll(deleted) -- we are removing bunch of elements from an ArrayList that has to move all affected elements on every deletion!
For instance, with the first 100_000 natural numbers, it takes about 10 seconds on my computer. Clearly, I looked for an alternative. What if we devise another list and collect the elements that we want to retain, and then in the next iteration, this list of retained elements becomes our list to operate on? It looked like that will work better because there is no deletion of elements involved. You will still need to have another ArrayList to collect the elements. In analysis terms, this is an O(n) additional space (or c.n where c ~ 0.5).
Here's my second attempt then:
private static void printLucky2(int n) {
List<Integer> numbers = Stream.iterate(1, k -> k + 1).limit(n).collect(Collectors.toList());
System.out.println(numbers);
int delIndex = 1; // index of the element to be removed, we start with 2nd element
while (delIndex < numbers.size()) {
List<Integer> retained = new ArrayList<>();
for (int i = 0; i < numbers.size(); i += 1)
if ((i+1) % (delIndex + 1) != 0)
retained.add(numbers.get(i));
numbers = retained;
System.out.println(numbers);
delIndex += 1;
}
System.out.println("number of lucky numbers:" + numbers.size());
System.out.println(numbers);
}
There may be more improvements possible because for really large inputs the time taken by this algorithm may still be unacceptable (will work on that improvement). But I already see two orders of magnitude improvement!
Here's the complete code. I made sure that both the methods return lists that are same (list1.equals(list2) returns true) and here is the output on my computer (with first 100_000 numbers):
[1, 3, 7, ...]
number of lucky numbers: 357
time taken: 6297
number of lucky numbers: 357
[1, 3, ...]
time taken: 57
for anyone still interested, I found another way to do this.
It isn't revolutionary or anything, and it uses a lot of the stuff the people on this thread told me, but it sort of summarizes all the advice I guess.
I felt it only fair to post my answer.
So, it involves iterating through every element, storing all the elements you need to remove in each round of counting, and then using the removeAll function to remove them before the count increases.
Here's the complete code for anyone interested. Any comments would also be welcome.
import java.util.*;
class luckyy
{
public static void main(String args[])
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter n: ");
int i, n, index;
n = scan.nextInt();
ArrayList <Integer> ele = new ArrayList <Integer> (n);
ArrayList <Integer> toRemove = new ArrayList <Integer> (n);
//storing in a list
for(i = 1;i<=n;i++)
{
ele.add(i);
}
System.out.println(ele);
int count = 2;
System.out.println("Size: "+ele.size());
while(count<=ele.size())
{
for(i = 0;i<ele.size();i++)
{
if((i+1)%count == 0)
{
toRemove.add(ele.get(i));
}
}
ele.removeAll(toRemove);
toRemove.clear();
count++;
}
System.out.println(ele);
}
}
There it is! It works, and boy am I glad! If anyone has any further advice, or anything else for me to learn or checkout, you are totally welcome to comment.
Thanks again everyone!

find unique elements from sorted array with complexity < O(n) [duplicate]

This question already has answers here:
Finding unique numbers from sorted array in less than O(n)
(5 answers)
Closed 8 years ago.
An interveiewer asked me below question:
Search out unique integer values(approx. 1000) from a sorted array of billion records(like 1,1,1,1,3,3,3,4,5,5,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8...........) with complexity less than O(n).
NOTE: NOt to use SET.
One solution that i tried to implement:
Divide that array into two set of arrays,then iterate both subarrays and search in hashmap if element doesnot exit,then add it into hashmap otherwise move to next iteration.
public static void main(String[] args) {
int arr[] = {1,2,4,9,-3,5,6,3,6,12,5,6,2,-1,-3,6,87,9,2,3,5,7,9,1,0,1,3,5,7,6,3,8,6,3,21,45,6};
int size1 =0, size2 = 0;
HashMap<Integer, Integer> map = new HashMap<Integer,Integer>();
System.out.println("length of Array:"+arr.length);
if((arr.length)%2 == 0){
size1 = size2 = arr.length/2;
}else{
size1 = (arr.length + 1)/2;
size2 = (arr.length)/2;
}
for(int i=0;((size1-i-1)>= 0)||((size2+i)<(arr.length - 1));i++){
if(map.containsKey(arr[size1 -i-1])== false){
map.put(arr[size1 -i-1],arr[size1 -i-1]);
}
if(map.containsKey(arr[size2 + i]) == false){
map.put(arr[size2 + i], arr[size2 + i]);
}
}
System.out.println(map.keySet());
}
And its working as expected, then he asked what if we divide the array into n sets?
then the complexity would be O(1) or O(n/n)? Is it possible?
Please suggest if there is another way to implement the same without using hashmap?
I'd try a binary search based approach, start from the middle element - if it's identical to one of the edges, then you can use the fact the array is sorted and eliminate that half. If it's different from each of the ones on the edges - divide the array into halves and proceed on each of them recursively.
This is still O(n) in the worst case, but on average it may be better then passing over the entire array (especially if there are many repetitions)
example -
1 1 1 1 1 2 2 2 2
could be done in two steps
why don't you use a Set instead of Map. Anyways, Set does not allow duplicate elements.
public static void main(String[] args) {
int arr[] = { 1, 2, 4, 9, -3, 5, 6, 3, 6, 12, 5, 6, 2, -1, -3, 6, 87,
9, 2, 3, 5, 7, 9, 1, 0, 1, 3, 5, 7, 6, 3, 8, 6, 3, 21, 45, 6 };
Set<Integer> aset = new HashSet<Integer>();
System.out.println("length of Array:" + arr.length);
for (int i : arr) {
aset.add(i);
}
System.out.println(aset);
}

How to take the first and last value from an arraylist inside an arraylist of arrylist using java

How to take the first and last value from an arraylist inside an arraylist of arrylist and check the adjacent values of other arraylist values in java?
for example:
This is my arraylist of arraylist
[[1,0],[2,0],[3,3],[1,0,0]]
This arraylist size can be any thing not consatant and the values indside this arraylist will varies.
What I need here is [1,0] from this value it should take the first value and last value and need to check with all the other values from the arraylist of arraylist. If the adjacent values are same then it should store in a different place and need to display it.
I need a output like this:
group :0
1,0
1,0,0
group:1
2,0
group:3
3,3
If the first and last values are same it should go to one group and remaining different group and it need to display all the values.
This is the code I tried but i am very new to java. so my code is not that good .please help me to find this output.
for (int a = 0; a < pattrn.size(); a++) {
// System.out.println(pat.size());
first = pattrn.get(a);
break;
}
System.out.println(first);
String temp = first.toString().replace("[", "").replace("]", "");
System.out.println(temp);
StringTokenizer firstvar = new StringTokenizer(temp, ", ");
firstvalue = firstvar.nextToken();
System.out.println("first value.." + firstvalue);
while (firstvar.hasMoreTokens()) {
lastvalue = firstvar.nextToken();
System.out.println("last value.." + lastvalue);
}
using this code I am not able to find this output.
There is no need to convert your Lists into Strings.
The List class allows objects to be retrieved by indexes. So keeping in mind that indexes are 0 based for List in Java, you can do this:
List<List<Integer>> collection = new ArrayList<List<Integer>>();
//Some initialization to get to this: [[1,0],[2,0],[3,3],[1,0,0]]
//The [1,0] list can be retrieved by the index 0
List<Integer> list = collection.get(0);
//Then you can do the same thing on that list to get the first value
Integer integer = list.get(0); //This will be 1
Then to get the last value in a list, you can use the size() method. This returns the size of the list. So in your case, that is 4. But remember that indexes start at 0, so to get the final element in a list, you use size() - 1 as the index.
//Then the following line will give you the last List of [1,0,0]
List<Integer> list = collection.get( collection.size() - 1 );
//Then you can do the same thing on that list to get the last value
//The size here will be 3 of course as this is the [1,0,0] list
Integer integer = list.get( list.size() - 1 ); //This will be 0
Of course, you can combine these with loops of ints to loop though all of the indexes of a particular list and then do the comparisons.
I've written a program that does what you're looking for and placed it here. I've also tried to explain what I'm doing at each stage as it might make use of things you're not familiar with if you're new to Java.
Edit: Eventual Solution
The OP revealed in the comments that the elements in the lists must be Strings and not Integers as the items being processed may contain letters.
Also revealed was that the solution I had produced had a couple of issues. When testing it with the input [[1,0],[2,0],[3,3],[1,0,0],[2,0],[2,0,0],[0,0],[1,2]] it became apparent there were issues around the group numbers being assigned giving NullPointerExceptions during printing. Also, there was an issue where some lists would not be grouped appropriately due to concurrent modification of lists.
Having fixed the above issues, I produced this version of my code which fully solved this issue.
Well, idk about the rest, but this is how you get the first and the last of each part of the array.
public static int[][] myArray = {
{ 1, 2, 3 },
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4, 5 },
{ 1, 2, 3, 4 },
{ 1, 2, 3 },
{ 1, 2, 3, 4, 5 },
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },
{ 1, 2, 3, 4, 5, 6, 7 },
};
It's fairly simple to get the first and last, just run a loop over the array like so:
public static void main(String[] args) {
for (int i = 0; i < myArray.length; i++) {
int first = myArray[i][0]; // first value
int last = myArray[i][myArray[i].length - 1]; // last
System.out.println("["+i+"]First: "+first+", Last: "+last+"");
}
}
Output would be:
[0]First: 1, Last: 3
[1]First: 1, Last: 4
[2]First: 1, Last: 5
[3]First: 1, Last: 4
[4]First: 1, Last: 3
[5]First: 1, Last: 5
[6]First: 1, Last: 4
[7]First: 1, Last: 10
[8]First: 1, Last: 10
Hope this helped atleast some ^-^
EDIT: Also adding an array to an array list works the same way:
public static ArrayList<int[]> myList = new ArrayList<int[]>();
static {
myList.add(new int[] { 1, 2 });
myList.add(new int[] { 1, 2, 3 });
myList.add(new int[] { 1, 2, 3, 4 });
myList.add(new int[] { 1, 2, 3, 4, 5 });
myList.add(new int[] { 1, 2, 3, 4, 5, 6 });
myList.add(new int[] { 1, 2, 3, 4, 5, 6, 7 });
myList.add(new int[] { 1, 2, 3, 4, 5, 6, 7, 8 });
myList.add(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9});
myList.add(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
}
public static void main(String[] args) {
for (int i = 0; i < myList.size(); i++) {
int first = myList.get(i)[0]; // first value
int last = myList.get(i)[myList.get(i).length - 1]; // last
System.out.println("["+i+"] First: "+first+", Last: "+last+"");
}
}
Output:
[0]First: 1, Last: 2
[1]First: 1, Last: 3
[2]First: 1, Last: 4
[3]First: 1, Last: 5
[4]First: 1, Last: 6
[5]First: 1, Last: 7
[6]First: 1, Last: 8
[7]First: 1, Last: 9
[8]First: 1, Last: 10

Categories