compare two arraylists and get position of common elements - java

I have two arraylists and the second one is a subset of the first.
I want to know the initial and final position in the first arraylist of elements in the subset (in my example the position in arrayList of: uno, due, tre)
How to modify this code?
import java.util.ArrayList;
public class ConfrontaArrayList {
public static void main(String[] args)
{
ArrayList<String> arrayList = new ArrayList<String>();
ArrayList<String> subSetArrayList = new ArrayList<String>();
arrayList.add("inizio");
arrayList.add("stringa");
arrayList.add("uno");
arrayList.add("due");
arrayList.add("tre");
arrayList.add("fine");
arrayList.add("stringa");
subSetArrayList.add("uno");
subSetArrayList.add("due");
subSetArrayList.add("tre");
System.out.print("Elementi di arrayList: ");
for (String stringa : arrayList) System.out.print(stringa + " ");
System.out.print("\nElementi di subSetArrayList: ");
for (String stringa : subSetArrayList) System.out.print(stringa + " ");
}
}

java.util.Collections.indexOfSubList() method will return the index of the sub list:
int startIdx = Collections.indexOfSubList(arrayList, subSetArrayList);
if (-1 != startIdx)
{
int endIdx = startIdx + subSetArrayList.size() - 1;
}

If you can't do the whole problem break it down into smaller steps that you can do:
How do you tell if two elements match?
Given 1, how do you tell if two equal-length lists match?
Given 2, how do you tell if a list matches at a given index in a longer list?
Given 3, how can you answer your problem?

The simplest answer is of course to iterate over the arraylist and do a String.equals() to find the index.

Use the indexOf method of ArrayList.
for(String item : subSetArrayList)
{
int index = arrayList.indexOf(item);
}
On 2nd thought, if SubsetArrayList items are in same sequence and in contigous order. you can do as following:
int startIndex = arrayList.indexOf(subSetArrayList.get(0));
int endIndex = startIndex + subSetArrayList.size() - 1;

Related

Java Sliding Window Problem: Given a string, find the length of the longest substring, which has all distinct characters. Comparing Solutions

I am taking a course to prepare for coding interviews and how it works is I try a problem then the solution is presented.
Question:
Given a string, find the length of the longest substring, which has all distinct characters.
Example:
Input: String="aabccbb"
Output: 3
Explanation: The longest substring with distinct characters is "abc".
I was wondering if there is any reason to use a HashMap and not an ArrayList on this problem? I will show both solutions and I was wondering if mine is wrong for any reason or if it is inefficient?
My solution works and the output matches (3,2,3). That's why I am wondering if I am doing anything wrong because their solution seems so much more complex than needed?
My Solution:
import java.util.*;
class NoRepeatSubstring {
public static int findLength(String str) {
// TODO: Write your code here
List<Character> charList = new ArrayList<Character>();
int maxLength = 0;
for(int windowEnd = 0; windowEnd < str.length(); windowEnd++) {
while(charList.contains(str.charAt(windowEnd))) {
charList.remove(0);
}
charList.add(str.charAt(windowEnd));
if(charList.size() > maxLength) {
maxLength = charList.size();
}
}
return maxLength;
}
public static void main(String[] args) {
System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("aabccbb"));
System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("abbbb"));
System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("abccde"));
}
}
Their Solution:
import java.util.*;
class NoRepeatSubstring {
public static int findLength(String str) {
int windowStart = 0, maxLength = 0;
Map<Character, Integer> charIndexMap = new HashMap<>();
// try to extend the range [windowStart, windowEnd]
for (int windowEnd = 0; windowEnd < str.length(); windowEnd++) {
char rightChar = str.charAt(windowEnd);
// if the map already contains the 'rightChar', shrink the window from the beginning so that
// we have only one occurrence of 'rightChar'
if (charIndexMap.containsKey(rightChar)) {
// this is tricky; in the current window, we will not have any 'rightChar' after its previous index
// and if 'windowStart' is already ahead of the last index of 'rightChar', we'll keep 'windowStart'
windowStart = Math.max(windowStart, charIndexMap.get(rightChar) + 1);
}
charIndexMap.put(rightChar, windowEnd); // insert the 'rightChar' into the map
maxLength = Math.max(maxLength, windowEnd - windowStart + 1); // remember the maximum length so far
}
return maxLength;
}
public static void main(String[] args) {
System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("aabccbb"));
System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("abbbb"));
System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("abccde"));
}
}
charList.contains(str.charAt(windowEnd)) is O(n) while charIndexMap.containsKey(rightChar) is (usually) O(1).
charList.contains goes through the whole list to check if the character is in the list.
charIndexMap.containsKey hashes the character/key, which is constant in time.
(It would be even faster to use an array of booleans with a fixed size of 2^8 (=the number of possible characters) and use the character as index into the array. That would be guaranteed to be O(1) and would also be faster with small strings since no time is wasted on computing hashes.)
ArrayList's contains method is O(N) but of HashMap is mostly O(1). Infact you dont even need to use a HashMap here , even HashSet will do.

Looping through arraylist of arraylists

I have this code below to count the frequency of a string in an ArrayList
public static int count (ArrayList<String> c, String str){
int num = 0;
num = Collections.frequency(c, str);
return num;
}
What I have to do now is to improve this so that the function takes in ArrayList<ArrayList<String>> and can loop through the set of Arraylists and Count the occurrences of the String. Any ideas would be great.
You need to use two nested for loops, looping through each list with the first one and looping through each element of the current list with the second, i.e.:
int count = 0;
for (ArrayList<String> list : lists) {
for (String string : list) {
if (list.equals("something")) count++;
}
}
To compute the frequency you'll also need to count the total number of elements in all the lists, but I'll leave that to you as it should be straightforward now.
Dude, you described the algorithm, it won't get simpler than that. Just code the thing.
Keep in mind that Collections::frequency is misnamed (IMHO), it should be count.
In java 8 use the stream
public void findOccurenceInLists(ArrayList<ArrayList<String>> lists, String myStr) throws Exception {
int occurence = 0;
lists.stream().forEach((list) -> {
occurence += list.stream().filter((str) -> str.equals(myStr)).count();
});
System.out.println(occurence + " occurence found");
}

Counting occurrences in a string array and deleting the repeats using java

i'm having trouble with a code. I have read words from a text file into a String array, removed the periods and commas. Now i need to check the number of occurrences of each word. I managed to do that as well. However, my output contains all the words in the file, and the occurrences.
Like this:
the 2
birds 2
are 1
going 2
north 2
north 2
Here is my code:
public static String counter(String[] wordList)
{
//String[] noRepeatString = null ;
//int[] countArr = null ;
for (int i = 0; i < wordList.length; i++)
{
int count = 1;
for(int j = 0; j < wordList.length; j++)
{
if(i != j) //to avoid comparing itself
{
if (wordList[i].compareTo(wordList[j]) == 0)
{
count++;
//noRepeatString[i] = wordList[i];
//countArr[i] = count;
}
}
}
System.out.println (wordList[i] + " " + count);
}
return null;
I need to figure out 1) to get the count value into an array.. 2) to delete the repetitions.
As seen in the commenting, i tried to use a countArr[] and a noRepeatString[], in hopes of doing that.. but i had a NullPointerException.
Any thought on this matter will be much appreciated :)
I would first convert the array into a list because they are easier to operate on than arrays.
List<String> list = Arrays.asList(wordsList);
Then you should create a copy of that list (you'll se in a second why):
ArrayList<String> listTwo = new ArrayList<String>(list);
Now you remove all the duplicates in the second list:
HashSet hs = new HashSet();
hs.addAll(listTwo);
listTwo.clear();
listTwo.addAll(hs);
Then you loop through the second list and get the frequency of that word in the first list. But first you should create another arrayList to store the results:
ArrayList<String> results = new ArrayList<String>;
for(String word : listTwo){
int count = Collections.frequency(list, word);
String result = word +": " count;
results.add(result);
}
Finally you can output the results list:
for(String freq : results){
System.out.println(freq);}
I have not tested this code (can't do that right now). Please ask if there is a problem or it doesnÄt work. See these questions for reference:
How do I remove repeated elements from ArrayList?
One-liner to count number of occurrences of String in a String[] in Java?
How do I clone a generic List in Java?
some syntax issues in your code but works fine
ArrayList<String> results = new ArrayList<String>();
for(String word : listTwo){
int count = Collections.frequency(list, word);
String result = word +": "+ count;
results.add(result);
}

How would I sort an ArrayList based on how another ArrayList acts? (java)

Here's ultimately what I need to do:
I have an ArrayList called originalList that looks like
[pans, pots, sit, it's, naps]
and another ArrayList called modifiedList that takes originalList and removes punctuation and uppercase and then sorts the list. So it would look like
[anps, anps, ist, ist, opst]
modifiedList's purpose is to tell me what words are anagrams of each other. An anagram is a word that consist of the same letters. The problem is I need to sort originalList to match modifiedList so that I can output what words are anagrams of each other. originalList would need to become [pans, naps, sit, it's, pots]. Suggestions?
Don't use an additional list. Sort your original list using a comparator that "normalizes" the two words to compare, and then compares their normalized values (by normalizing, I mean transforming naps into anps).
You'll then have your anagrams next to each other in the list.
public static void main(String args[]){
ArrayList<String> alOriginal = new ArrayList<String>();
alOriginal.add("pans");
alOriginal.add("pots");
alOriginal.add("sit");
alOriginal.add("it's");
alOriginal.add("naps");
ArrayList<String> alAnagram = getSortedAnagramStrings(alOriginal);
System.out.println(alOriginal);
System.out.println(alAnagram);
}
public static java.util.ArrayList<String> getSortedAnagramStrings(ArrayList<String> original){
ArrayList<String> alAnagramStrings = new ArrayList<String>();
for (String currentString : original) {
// Remove punctuation
char[] anagramChars = currentString.replace("'", "").toCharArray();
// Sort characters
Arrays.sort(anagramChars);
// Prepare string
String anagramString = new String(anagramChars);
// Add to array list
alAnagramStrings.add(anagramString);
}
// Simple sort logic
for (int index = 0; index < alAnagramStrings.size(); index ++){
for (int index1 = index + 1; index1 < alAnagramStrings.size(); index1 ++){
// If both anagram strings are same
if(alAnagramStrings.get(index).compareTo(alAnagramStrings.get(index1)) == 0){
// Compare original strings
if (original.get(index).compareTo(original.get(index1)) > 0){
String temp =original.get(index);
original.set(index, original.get(index1));
original.set(index1, temp);
}else{
String temp =original.get(index);
original.set(index1, original.get(index));
original.set(index, temp);
}
}else if(alAnagramStrings.get(index).compareTo(alAnagramStrings.get(index1)) > 0){
String temp =alAnagramStrings.get(index);
alAnagramStrings.set(index, alAnagramStrings.get(index1));
alAnagramStrings.set(index1, temp);
String temp1 =original.get(index);
original.set(index, original.get(index1));
original.set(index1, temp1);
}
}
}
return alAnagramStrings;
}

Java - find indexof for part of a needle in array haystack

I am trying to find what array index position contains part of a string.
FullDirPrt = "a1a" "b2b" "c3c"
String doT ="b2";
int DotPos = Arrays.asList(FullDirPrt).indexOf(doT);
If I search for b2b it returns indexOf. If I search for only b2, it returns -1.
You have to check each item in the array individually, as each array item is a separate string:
String[] full = { "a1a", "b2b", "c3c" };
String doT = "b2";
for(int i = 0; i < full.length; i++) {
if(full[i].contains(doT)) {
System.out.println("Found item at index " + i);
}
}
You are matching on the entire string, you are going to have to loop through the whole list or array, and then check each indexOf on each of those strings.
for (String s : FullDirPrt) {
if (s.indexOf("bs") > 0) {
// do something
}
}
With Simple String array without using List also you can do like below.
String[] full={"a1a", "b2b", "c3c"};
String doT = "b2";
for(String str:full){
if(str.contains(doT)){
System.out.println(str+" contains "+doT);
}
}

Categories