How can I get duplicate values from ArrayList? - java

I have a ArrayList: ArrayList<String> buffer = new ArrayList<String>();
How can I take duplicated values from ArrayList?
Example:
fsfs.txt
erwre.txt
wery.txt
wtrtr.txt
erwre.txt
qweq.txt
My attempts:
With cycles:
for(int i = 0; i < buffer.size(); i++) {
for(int j = i + 1; j < buffer.size(); j++) {
if( buffer.get(i).equals(buffer.get(j)) ) {
bufferTemp.add(j, buffer.toString() );
j--;
}
}
}
With iterator:
Iterator<String> i = buffer.iterator();
Iterator<String> j = buffer.iterator();
j.next();
while(i.hasNext() && j.hasNext()) {
if( i.next().equals(j.next() )
System.out.println(i.next());
}
Also I try to use Comparable, Comparator and other ways but it don't work.

You can create a Set passing the your list as a argument. Set will take care of duplicates.
private static List<String> list = new ArrayList<String>();
public static void main(String[] args) {
list.add("aaa.txt");
list.add("aaa.txt");
list.add("aaa.txt");
list.add("bbb.txt");
list.add("ccc.txt");
list.add("ccc.txt");
Set<String> set = new HashSet<String>(list);
System.out.println(set);
}

If I understand you correctly, you use Java and want to get the duplicates of an ArrayList.
If you use Strings, then you can just sort the List and compare in a loop the previous with the current element. Look at this (Java 7):
ArrayList<String> list = new ArrayList<>();
list.add("fsfs.txt");
list.add("erwre.txt");
list.add("wery.txt");
list.add("wtrtr.txt");
list.add("erwre.txt");
list.add("qweq.txt");
// Sort the list
Collections.sort(list);
// Test if List was sorted correctly
for(String s : list)
{
System.out.println(s);
}
System.out.println("\n*** Now try to get duplicates ***\n");
Iterator<String> listIt = list.iterator();
String prev = "";
boolean foundDuplicate = false;
while(listIt.hasNext())
{
String current = listIt.next();
if(current.equals(prev))
foundDuplicate = true;
else
foundDuplicate = false;
if(foundDuplicate)
{
// Duplicate found!
System.out.println(current);
}
prev = current;
}
Output should be:
erwre.txt
erwre.txt
fsfs.txt
qweq.txt
wery.txt
wtrtr.txt
*** Now try to get duplicates ***
erwre.txt

Related

Get largest Group of anagrams in an array

For an assignment I have been asked to find the largest group of anagrams in a list. I believe I would have to have an accumulation loop inside of another loop that keeps track of the largest number of items. The problem is that I don't know how to count how many of each anagram I have. I have been able to sort the array into groups based on their anagrams. So from the index 1-3 is one anagram, 4-10 is another, etc. How do I search through and count how many of each anagram I have? Then compare each one to the previous count.
Sample of the code:
public static String[] getLargestAnagramGroup(String[] inputArray) {
ArrayList<String> largestGroupArrayList = new ArrayList<String>();
if (inputArray.length == 0 || inputArray == null) {
return new String[0];
}
insertionSort(inputArray, new AnagramComparator());
String[] largestGroupArray = new String[largestGroupArrayList.size()];
largestGroupArrayList.toArray(inputArray);
System.out.println(largestGroupArray);
return largestGroupArray;
}
UPDATE: This is how we solved it. Is there a more efficient way?
public static String[] getLargestAnagramGroup(String[] inputArray) {
int numberOfAnagrams = 0;
int temporary = 1;
int position = -1;
int index = 0;
if (inputArray == null) {
return new String[0];
}
insertionSort(inputArray, new AnagramComparator());
for (index = 0; index < inputArray.length - 1; index++) {
if (areAnagrams(inputArray[index], inputArray[index + 1])) {
temporary++;
} else {
if (temporary > numberOfAnagrams) {
numberOfAnagrams = temporary;
position = index;
temporary = 1;
} else if (temporary < numberOfAnagrams) {
temporary = 1;
}
}
}
if (temporary > numberOfAnagrams) {
position = index;
numberOfAnagrams = temporary;
}
String[] largestArray = new String[numberOfAnagrams];
for (int startIndex = position - numberOfAnagrams + 1, i = 0; startIndex <= position; startIndex++, i++) {
largestArray[i] = inputArray[startIndex];
}
return largestArray;
}
Here is a piece of code to help you out.
public class AnagramTest {
public static void main(String[] args) {
String[] input = {"test", "ttes", "abcd", "dcba", "dbac"};
for (String string : getLargestAnagramGroup(input)) {
System.out.println(string);
}
}
/**
* Gives an array of Strings which are anagrams and has the highest occurrence.
*
* #param inputArray
* #return
*/
public static String[] getLargestAnagramGroup(String[] inputArray) {
// Creating a linked hash map to maintain the order
Map<String, List<String>> map = new LinkedHashMap<String, List<String>>();
for (String string : inputArray) {
char[] charArray = string.toCharArray();
Arrays.sort(charArray);
String sortedStr = new String(charArray);
List<String> anagrams = map.get(sortedStr);
if (anagrams == null) {
anagrams = new ArrayList<String>();
}
anagrams.add(string);
map.put(sortedStr, anagrams);
}
Set<Entry<String, List<String>>> entrySet = map.entrySet();
List<String> l = new ArrayList<String>();
int highestAnagrams = -1;
for (Entry<String, List<String>> entry : entrySet) {
List<String> value = entry.getValue();
if (value.size() > highestAnagrams) {
highestAnagrams = value.size();
l = value;
}
}
return l.toArray(new String[l.size()]);
}
}
The idea is to first find the anangrams. I am doing that using a sorting the string's character array and using the LinkedhashMap.
Then I am storing the original string in the list which can be used to print or reuse as a result.
You have to keep counting the number of times the an anagram occurs and that value can be used solve your problem
This is my solution in C#.
public static string[] LargestAnagramsSet(string[] words)
{
var maxSize = 0;
var maxKey = string.Empty;
Dictionary<string, List<string>> set = new Dictionary<string, List<string>>();
for (int i = 0; i < words.Length; i++)
{
char[] temp = words[i].ToCharArray();
Array.Sort(temp);
var key = new string(temp);
if (set.ContainsKey(key))
{
set[key].Add(words[i]);
}
else
{
var anagrams = new List<string>
{
words[i]
};
set.Add(key, anagrams);
}
if (set[key].Count() > maxSize)
{
maxSize = set[key].Count();
maxKey = key;
}
}
return string.IsNullOrEmpty(maxKey) ? words : set[maxKey].ToArray();
}

Java: how to count non-repeated (occurring only once) Strings in ArrayList?

I am trying to find the number of Strings that only appear exactly once in an ArrayList.
How many I achieve this (preferably with the best possible time complexity)?
Below is my method:
public static int countNonRepeats(WordStream words) {
ArrayList<String> list = new ArrayList<String>();
for (String i : words) {
list.add(i);
}
Collections.sort(list);
for (int i = 1; i < list.size(); i++) {
if (list.get(i).equals(list.get(i - 1))) {
list.remove(list.get(i));
list.remove(list.get(i - 1));
}
}
System.out.println(list);
return list.size();
}
Why doesn't it remove the String at list.get(i) and list.get(i-1)?
There is no need for sorting.
A better approach would be to use two HashSet One for maintaining repeating and one for non-repeating words. Since HashSet internally uses HashMap, Ideally contains, get, put operation has o(1) complexity. So the overall complexity of this approach would be o(n).
public static int countNonRepeats(List<String> words) {
Set<String> nonRepeating = new HashSet<String>();
Set<String> repeating = new HashSet<String>();
for (String i : words) {
if(!repeating.contains(i)) {
if(nonRepeating.contains(i)){
repeating.add(i);
nonRepeating.remove(i);
}else {
nonRepeating.add(i);
}
}
}
System.out.println(nonRepeating.size());
return nonRepeating.size();
}
Here's one simple suggestion:
First, sort your array by alphanumerical order
Iterate through with a loop, if( !list.get(i).equals(list.get(i+1)) ) → unique
If you find duplicates, increment i until you reach a different string
This will have the complexity of the sorting algorithm, since step 2+3 should be O(n)
Is there any specific need of using an ArrayList? You can do it easily by using a HashSet.
Here is the code snippet:
public static void main (String[] args) {
String[] words = {"foo","bar","foo","fo","of","bar","of","ba","of","ab"};
Set<String> set = new HashSet<>();
Set<String> common = new HashSet<>();
for (String i : words) {
if(!set.add(i)) {
common.add(i);
}
}
System.out.println(set.size() - common.size());
}
Output:
3
Here is the modified code:
public static int countNonRepeats(WordStream words) {
Set<String> set = new HashSet<>();
Set<String> common = new HashSet<>();
for (String i : words) {
if(!set.add(i)) {
common.add(i);
}
}
return (set.size() - common.size());
}
You can use hashmap to achieve this.With this approach we can count the occurrence of all the words, If we are interested in only unique words then access the element having count = 1.
HashMap<String,Integer> - key represents the String from arraylist and Integer represents the count of occurrence.
ArrayList<String> list = new ArrayList<String>();
HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
for (int i = 0; i < list.size(); i++) {
String key = list.get(i);
if (hashMap.get(key) != null) {
int value = hashMap.get(key);
value++;
hashMap.put(key, value);
} else {
hashMap.put(key, 1);
}
}
int uniqueCount = 0;
Iterator it = hashMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
if ((int) pair.getValue() == 1)
uniqueCount++;
}
System.out.println(uniqueCount);

IF condition and looping through an ArrayList

The method on the top should merge two String elements in an ArrayList that are side by side with each other. If the length of the ArrayList is Odd the last String element should be left unchanged.
But the problem is that is this way the program leaves the first String element alone, while the others are merged nicely. The output looks like this:
[1, 23, 45, 67, 89]
although it has to look like this:
[12, 34, 56, 78, 9]
How is it possible to fix the problem? Preferably without using the Iterator.
import java.util.ArrayList;
public class Main {
public static ArrayList<String> clump (ArrayList<String> list)
{
for (int i =0; i< list.size(); i++)
//for (int i = list.size()-1; i >=0; i--)
{
// if (i == 0)
if ((list.size() + i) % 2 == 0) {
System.out.println(list);
System.out.println("list size is " + list.size());
String newElement = list.get(i) + list.get(i+ 1);
list.remove(i);
list.remove(i);
list.add(i, newElement);
//System.out.println(list);
}
else {
continue;
}
}
return list;
}
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
list.add("7");
list.add("8");
list.add("9");
System.out.println(clump(list));
}
}
Your code seems to work fine if the input list has even number of elements. For the case when you have odd number of elements in the list, remove the last element from the list and save it temporarily before running your code. Add the last element back to the output returned.
This can be one solution (may not be the best solution):
import java.util.ArrayList;
public class Main {
public static ArrayList<String> clump (ArrayList<String> list)
{
// BEGIN CHANGES MADE
String temp = null;
int size = list.size();
if ((size%2) != 0)
{
temp = list.remove(size-1);
}
// END CHANGES MADE
for (int i =0; i< list.size(); i++)
{
if ((list.size() + i) % 2 == 0) {
System.out.println(list);
System.out.println("list size is " + list.size());
String newElement = list.get(i) + list.get(i+ 1);
list.remove(i);
list.remove(i);
list.add(i, newElement);
//System.out.println(list);
}
else {
continue;
}
}
// BEGIN CHANGES MADE
if (temp != null)
{
list.add(temp);
}
// END CHANGES MADE
return list;
}
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
list.add("7");
list.add("8");
list.add("9");
//list.add("0");
System.out.println(clump(list));
}
}
You don't need to check if ((list.size() + i) % 2 == 0). On every iteration you can concatenate adjacent elements.
Also, you will need to loop until i < list.size()-1 instead of i < list.size() because when you remove the 2nd last element, you are already at the last index.
So remove the if-else block if ((list.size() + i) % 2 == 0).
and replace:
for (int i =0; i< list.size(); i++)
with:
for (int i = 0; i < list.size() - 1; i++)
Here is a working version of your program:
import java.util.ArrayList;
class So {
public static ArrayList<String> clump(ArrayList<String> list) {
for (int i = 0; i < list.size() - 1; i++)
// for (int i = list.size()-1; i >=0; i--)
{
// if (i == 0)
System.out.println(list);
System.out.println("list size is " + list.size());
String newElement = list.get(i) + list.get(i + 1);
list.remove(i);
list.remove(i);
list.add(i, newElement);
// System.out.println(list);
}
return list;
}
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
list.add("7");
list.add("8");
list.add("9");
System.out.println(clump(list));
}
}
I hope it helps you out. I used your code. It was enough good idea. Some change helped on it to work fine. Try it out! :D
import java.util.ArrayList;
public class Main {
public static ArrayList<String> clump (ArrayList<String> list)
{
int halfSize = list.size()/2;
for (int i =0; i < halfSize; i++) {
System.out.println(list);
String newElement = list.get(i) + list.get(i+1);
list.remove(i);
list.remove(i);
list.add(i, newElement);
}
return list;
}
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
list.add("7");
list.add("8");
list.add("9");
list.add("10");
list.add("11");
list.add("12");
list.add("13");
System.out.println(clump(list));
}
}
private static ArrayList<String> clump(ArrayList<String> list) {
ArrayList<String> res = new ArrayList<String>();
Iterator<String> itr = list.iterator();
while (itr.hasNext()) {
res.add(itr.next() + (itr.hasNext() ? itr.next() : ""));
}
return res;
}
ArrayList<Integer> getMinCoins = new ArrayList<Integer>(); // function to receive change in the form of coins
{
for (int i: coins){
getMinCoins.add(i);
System.out.println(getMinCoins);
}
}

How can I combine elements at the same index from separate lists?

I am trying to combine multiple String lists.
Say I have two (could be more) lists of the same size:
List<String> list1 = Arrays.asList("1One","1Two","1Three");
List<String> list2 = Arrays.asList("2One","2Two","2Three");
I want to combine the value of the corresponding indexes and place them into a new list:
List3 = new {"1One2One", "1Two2Two", "1Three2Three"};
Currently I have a list of 2 objects, each object contains the list that I want to combine the elements within.
So I want to combine element 1 in the list from object 1 with element 1 from the list from object 2.
This is what I have attempted:
public void generateFileList(List<Object> cl){
int count = 0;
String temp = "";
for(int i = 0; i < cl.size(); i++){
for (int x = 0; x < cl.get(i).getItemList().size(); x++) {
if (count == x){
temp += cl.get(i).getListItem(x);
break;
}
}
count++;
textList.add(temp);
}
}
public void test(){
for(String s : textList){
System.out.println("List Element - " + s);
}
System.out.println(textList.size());
}
Which prints out:
List Element - 1One
List Element - 1One1Three
What am I doing wrong here?
First, the code you have won't compile. It should be:
List<String> list1 = Arrays.asList("1One","1Two","1Three");
List<String> list2 = Arrays.asList("2One","2Two","2Three");
Next, it is best to use an Iterator than access a List by index:
public List<String> concat(final List<String> list1, final List<String> list2) {
final Iterator<String> i1 = list1.iterator();
final Iterator<String> i2 = list2.iterator();
final List<String> combined = new ArrayList<>();
while (i1.hasNext() && i2.hasNext()) {
combined.add(i1.next() + i2.next());
}
return combined;
}
For an arbitrary number of List:
public List<String> concat(final List<String>... lists) {
final List<Iterator<String>> it = new LinkedList<>();
for (List<String> l : lists) {
it.add(l.iterator());
}
final List<String> combined = new ArrayList<>();
outer:
while (true) {
final StringBuilder sb = new StringBuilder();
for (final Iterator<String> i : it) {
if (!i.hasNext()) {
break outer;
}
sb.append(i.next());
}
combined.add(sb.toString());
}
for (final Iterator<String> i : it) {
if (i.hasNext()) {
throw new IllegalArgumentException("Lists not the same length.");
}
}
return combined;
}
If the lists have the same size, just have a for loop from 0 to list size, and add in the new list the concatenation of the elements from the same position in the two lists, like for (int i =0; i< list1.size(); i++) { resultedlist.add(list1.get(i) + list2.get(i))}
Presuming the 2 lists are the same size:
List<String> list1 = new {"1One","1Two","1Three"};
List<String> list2 = new {"2One","2Two","2Three"};
List<String> list3 = new ArrayList<>();
for (int i = 0; i < list1.size(); i++) {
list3.add(list1.get(i) + list2.get(i));
}

How do I add this row and column data to a HashMap?

I am trying to read a file which has say
Name,Date,Place
Tom,1/1/2010,America
Dick,2/2/2011,China
Harry,3/3/2012,Germany
And adds the column headers to a String and the values to an ArrayList.
HashMap<String columnName ,ArrayList<String> Value>
So the program should run like,
if(lineNumber == 1)
{
interate through values and create headers
}
else
add values to corresponding header list
My problem is I do not know how I can reference the arraylist in the else part of the code.
If anybody has done something similar I would like to hear from you !
Edit
So I have something like this so far,
public void consumeLine(String path,int lineNumber,List line){
if(lineNumber == 1)
{
ListIterator listIterator = line.listIterator();
while(listIterator.hasNext())
{
hashMap.put(listIterator.next().toString(),new ArrayList<String>());
}
}
You want to create an ordered list of the column names, and iterate through that as you iterate through the values in each row.
Something like this (untested code!):
ListIterator listIterator = line.listIterator();
if(lineNumber == 1)
{
while(listIterator.hasNext())
{
String key = listIterator.next().toString();
keyList.add(key); // keyList is a List<String> instance field.
hashMap.put(key, new ArrayList<String>());
}
} else {
Iterator<String> keyIterator = keyList.iterator();
while(keyList.hasNext() && listIterator.hasNext())
{
String key = keyList.next();
String value = listIterator.next();
ArrayList<String> values = hashMap.get(key);
values.add(value);
}
}
Try it:
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("file.txt"));
HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
int lineNumber = 1;
String[] columnName = null;
ArrayList<String[]> value = new ArrayList<String[]>(); // temp array
String line;
String[] arr;
while (reader.ready())
if (!(line = reader.readLine()).isEmpty()) {
arr = line.split("\\s+");
if (lineNumber == 1)
columnName = arr;// create headers
else
value.add(arr);// create values
lineNumber++;
}
// transform data
for (int i = 0; i < columnName.length; i++) {
ArrayList<String> ar = new ArrayList<String>();
for (int j = 0; j < value.size(); j++)
ar.add(value.get(j)[i]);
map.put(columnName[i], ar);
}
System.out.println(map);
}

Categories

Resources