Java - Iterate an ArrayList and Find Anagrams - java

I have a list of sorted canonical words and I would like to iterate the list with an iterator to find matching canonical words which would be having same Anagrams then add them to a seperate LinkedList paired together if they match. How would I go about doing this? Would I run two iterators at once for the same list and put them in a nested while loop with one iterator on the 1st element and the second iterator inside searching the same list for all elements for match then adding it to a List if a match is found? Any ideas?
Here's what I've done so far:
Driver Class File:
import java.util.*;
import java.io.*;
public class Programming9Driver {
public static void main(String[] theArgs) {
LinkedList<Word> wordObjects = new LinkedList<Word>();
ArrayList<String> localWords = new ArrayList<String>();
BufferedReader localInput = null;
BufferedWriter localOutput = null;
try {
String localLine;
localInput = new BufferedReader(new FileReader("words.txt"));
// localOutput = new BufferedWriter(new FileWriter("out9.txt"));
while ((localLine = localInput.readLine()) != null) {
if (localLine != "") {
localWords.add(localLine);
}
//
//
}
/*
*/
localInput.close();
// localOutput.close();
} catch (Exception e) {
System.out.println("Difficulties opening the file! " + e);
System.exit(1);
}
localWords.removeAll(Collections.singleton(""));
Map<String, List<String>> anagramList = new HashMap<String, List<String>>();
Iterator<String> iterAdd = localWords.iterator();
while (iterAdd.hasNext()) {
wordObjects.add(new Word(iterAdd.next()));
}
Collections.sort(wordObjects);
LinkedList<AnagramFamily> anagramObjects = new LinkedList<AnagramFamily>();
}
}
Word.java:
import java.util.*;
public class Word implements Comparable<Word>{
private String myWord;
private String myCanon;
private Map<String, List<String>> myCanonKey = new HashMap<String, List<String>>();
public Word(final String theWord) {
myWord = theWord;
myCanon = canonForm();
myCanonKey = canonWords();
}
public String canonForm() {
String canonWord = "";
Character[] localChars = new Character[myWord.length()];
for (int i = 0; i < localChars.length; i++) {
localChars[i] = myWord.charAt(i);
}
Arrays.sort(localChars);
for (int i = 0; i < localChars.length; i++) {
canonWord += localChars[i];
}
return canonWord;
}
public Map<String, List<String>> canonWords() {
ArrayList<String> canonList = new ArrayList<String>();
Map<String, List<String>> canonKey = new HashMap<String, List<String>>();
canonList.add(myWord);
canonKey.put(myCanon, canonList);
return canonKey;
}
public int compareTo(Word theOther) {
int result = canonForm().compareTo(theOther.canonForm());
return result;
}
public String toString() {
String result = "";
result = myWord;
if (myWord == "" || myCanon == "") {
result = "";
}
return result;
}
}
How would I call from my main driver program to use the canonWords() method from the Word class java file?

One way of going about it would be to iterate through all the strings, creating a new string from an alphabetically sorted char array of the original, and use your new string as the key in a Map<String, List<String>>.
EDIT: The code you posted seems a little over the top, to be honest. Here's a demonstration of what I had in mind:
Collection<LinkedList<String>> groupAnagrams(List<String> words) {
Map<String, LinkedList<String>> anagramMap = new HashMap<>();
for(String word : words) {
char[] wordChars = word.toCharArray();
Arrays.sort(wordChars);
String sortedKey = new String(wordChars);
LinkedList<String> anagramList = anagramMap.get(sortedKey);
if(anagramList == null) {
anagramMap.put(sortedKey, anagramList = new LinkedList<>());
}
anagramList.add(word);
}
return anagramMap.values();
}
EDIT 2: Just for fun, here's a Java 8 implementation:
Collection<List<String>> groupAnagrams(List<String> words) {
return words.stream().collect(groupingBy(w -> {
char[] chars = w.toCharArray();
Arrays.sort(chars);
return new String(chars);
})).values();
}

Related

Reversing a HashMap storing words and their line numbers

I have a HashMap
HashMap<String, LinkedList<Integer>> indexMap;
which is storing all words in a file and their corresponding line numbers where they appear.
Example -
This is just an example
to demonstrate what I am saying an is
Would display
This [1]
demonstrate [2]
an [1 2]
is [1 2]
...
....
And so on. I want to reverse this HashMap so that it displays the words stored at each line number.
For the particular example above, it should display
1 [This, an, just, example, is]
2 [demonstrate, what, to, I, am, saying, is, an]
For this particular task, this is what I have done -
import java.io.FileReader;
import java.io.LineNumberReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
public class ReverseIndex {
private static Map<String, LinkedList<Integer>> indexMap = new HashMap<String, LinkedList<Integer>>();
public static LinkedList<Integer> getIndex(String word) {
return indexMap.get(word);
}
public static void main(String[] args) {
try {
LineNumberReader rdr = new LineNumberReader(
new FileReader(
args[0]));
String line = "";
int lineNumber = 0;
//CREATING THE INITIAL HASHMAP WHICH WE WANT TO REVERSE
while ((line = rdr.readLine()) != null) {
lineNumber++;
String[] words = line.split("\\s+");
for (int i = 0; i < words.length; i++) {
LinkedList<Integer> temp = new LinkedList<Integer>();
if (getIndex(words[i]) != null)
temp = getIndex(words[i]);
temp.add(lineNumber);
indexMap.put(words[i], temp);
}
}
//FINISHED CREATION
Map<Integer, LinkedList<String>> myNewHashMap = new HashMap<Integer, LinkedList<String>>();
for(Map.Entry<String, LinkedList<Integer>> entry : indexMap.entrySet()){
LinkedList<Integer> values = entry.getValue();
String key = entry.getKey();
LinkedList<String> temp = new LinkedList<String>();
for(int i = 0; i <= lineNumber; i++) {
if(values.contains(i)) {
if(!temp.contains(key))
temp.add(key);
myNewHashMap.put(i, temp);
}
}
}
for(Map.Entry<Integer, LinkedList<String>> entry : myNewHashMap.entrySet()){
Integer tester = entry.getKey();
LinkedList<String> temp2 = new LinkedList<String>();
temp2 = entry.getValue();
System.out.print(tester + " ");
for(int i = 0; i < temp2.size(); i++) {
System.out.print(temp2.get(i) + " ");
}
System.out.println();
}
rdr.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
However the problem with this is, for the example that we had above, it would print -
1 example
2 an
How could I reverse it so that it works perfectly with the expected output?
Just replace the first for loop in your main with the below code. I have made some changes to you original code as per convention like moved variable declaration out of loop and changed the logic in a way it checks if the LinkedList<'String'> already exists for the line number if so add it to the list or else create a new LinkedList<'String'> and then add word.
LinkedList<Integer> values = null;
String key = null;
LinkedList<String> temp = null;
for(Map.Entry<String, LinkedList<Integer>> entry : indexMap.entrySet())
{
values = entry.getValue();
key = entry.getKey();
temp = new LinkedList<String>();
for(int value : values)
{
temp = myNewHashMap.get(value);
if(temp == null )
{
temp = new LinkedList<String>();
myNewHashMap.put(value,temp);
}
temp.add(key);
}
}

Java split string with combinations

My input string is
element1-element2-element3-element4a|element4b-element5-
Expected output is
element1-element2-element3-element4a-element5-
element1-element2-element3-element4b-element5-
So the dash (-) is the delimiter and the pipe (|) indicates two alternative elements for a position.
I am able to generate combinations for input containing a single pipe:
ArrayList<String> finalInput = new ArrayList<String>();
String Input = getInputPath();
StringBuilder TempInput = new StringBuilder();
if(Input.contains("|")) {
String[] splits = Input.split("\\|", 2);
TempInput.append(splits[0]+"-"+splits[1].split("-", 2)[1]);
finalInput.add(TempInput.toString());
TempInput = new StringBuilder();
String[] splits1 = new StringBuilder(Input).reverse().toString().split("\\|", 2);
finalInput.add(TempInput.append(splits1[0]+"-"+splits1[1].split("-", 2)[1]).reverse().toString());
}
But this logic fails if there are multiple pipe symbols.
How to split a String on the last occurrance only?
Is there any efficient way to use split String with combinations?
Input:
element1-element2-element3-element4a|element4b-element5-element6a|element6b
Output:
element1-element2-element3-element4a-element5-element6a
element1-element2-element3-element4b-element5-element6a
element1-element2-element3-element4a-element5-element6b
element1-element2-element3-element4b-element5-element6b
Recursion helps.
public static void main(String[] args) {
produce("element1-element2-element3-element4a|element4b"
+ "-element5-element6a|element6b");
}
private static void produce(String input) {
String[] sequence = input.split("-");
String[][] elements = new String[sequence.length][];
for (int i = 0; i < sequence.length; ++i) {
elements[i] = sequence[i].split("\\|");
}
List<String> results = new ArrayList<>();
walk(results, elements, 0, new StringBuilder());
}
private static void walk(List<String> results, String[][] elements,
int todoIndex, StringBuilder done) {
if (todoIndex >= elements.length) {
results.add(done.toString());
System.out.println(done);
return;
}
int doneLength = done.length();
for (String alternative : elements[todoIndex]) {
if (done.length() != 0) {
done.append('-');
}
done.append(alternative);
walk(results, elements, todoIndex + 1, done);
done.setLength(doneLength); // Undo
}
}
The String.split method is used twice to get a navigatable String[][]. And to build a final String a StringBuilder is used.
You can use StringTokenizer in Java. Basically it makes tokens of the string.
public StringTokenizer(String str, String delim)
Here's an example:
String msg = "http://100.15.111.60:80/";
char tokenSeparator= ':';
StringTokenizer st = new StringTokenizer(msg, tokenSeparator + "");
while(st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
I have write a demo for you as what I comment after your post, the code may be ugly, but it works
public class TestSplit {
//define a stringList hold our result.
private static List<String> stringList = new ArrayList<String>();
//this method fork the list array when we meet a "|"
public static void forkStringList(){
List<String> tmpList = new ArrayList<String>();
for(String s: stringList){
tmpList.add(s);
}
stringList.addAll(tmpList);
}
//when we meet "|" split two elems, should add it to
//the string list half-half
public static void addTowElems(String s1, String s2){
for(int i=0;i<stringList.size()/2;i++){
stringList.set(i,stringList.get(i)+s1);
}
for(int i = stringList.size()/2;i<stringList.size();i++){
stringList.set(i,stringList.get(i)+s2);
}
}
// if not meet with a "|" just add elem to everyone of the stringlist
public static void addOneElem(String s){
for(int i=0;i<stringList.size();i++){
stringList.set(i,stringList.get(i)+s);
}
}
public static void main(String[] argvs){
//to make *fork* run, we must make sure there is a "init" string
//which is a empty string.
stringList.add("");
// this is your origin string.
String input = "a-b-c-d|e-f";
for (String s: input.split("\\-")){
if(s.contains("|")){
//when meet with "|", first fork the stringlist
forkStringList();
// then add them separately
addTowElems(s.split("\\|")[0],s.split("\\|")[1]);
}else {
// else just happily add the elem to every one
// of the stringlist
addOneElem(s);
}
}
//checkout the result, should be expected.
System.out.println(stringList);
}
}
Here's my iterative solution:
import java.util.*;
public class PathParser {
private static final String DELIMINATOR_CONCAT = "-";
private static final String DELIMINATOR_OPTION = "|";
private List<String> paths;
private List<String> stack;
private List<String> parse(final String pathSpec) {
stack = new ArrayList<String>();
paths = new ArrayList<String>();
paths.add("");
final StringTokenizer tok = createStringTokenizer(pathSpec);
while (tok.hasMoreTokens()) {
final String token = tok.nextToken();
parseToken(token);
}
if (!stack.isEmpty()) {
updatePaths();
}
return paths;
}
private void parseToken(final String token) {
if (DELIMINATOR_CONCAT.equals(token)) {
updatePaths();
} else if (DELIMINATOR_OPTION.equals(token)) {
// nothing to do
} else {
stack.add(token);
}
}
private void updatePaths() {
final List<String> originalPaths = new ArrayList<String>(paths);
paths.clear();
while (stack.size() > 0) {
paths.addAll(createNewPaths(originalPaths));
}
}
private List<String> createNewPaths(final List<String> originalPaths) {
final List<String> newPaths = new ArrayList<String>(originalPaths);
addPart(newPaths, stack.remove(0));
addPart(newPaths, DELIMINATOR_CONCAT);
return newPaths;
}
private void addPart(final List<String> paths, final String part) {
for (int i = 0; i < paths.size(); i++) {
paths.set(i, paths.get(i) + part);
}
}
private StringTokenizer createStringTokenizer(final String pathSpec) {
final boolean returnDelimiters = true;
final String delimiters = DELIMINATOR_CONCAT + DELIMINATOR_OPTION;
return new StringTokenizer(pathSpec, delimiters, returnDelimiters);
}
public static void main(final String[] args) {
final PathParser pathParser = new PathParser();
final String input = "element1-element2-element3-element4a|element4b|element4c-element5-element6a|element6b|element6c";
System.out.println("Input");
System.out.println(input);
System.out.println();
final List<String> paths = pathParser.parse(input);
System.out.println("Output");
for (final String path : paths) {
System.out.println(path);
}
}
}
Output:
Input
element1-element2-element3-element4a|element4b-element5-element6a|element6b
Output
element1-element2-element3-element4a-element5-element6a-
element1-element2-element3-element4b-element5-element6a-
element1-element2-element3-element4a-element5-element6b-
element1-element2-element3-element4b-element5-element6b-
This helps to acheive the same..
public class MultiStringSplitter {
public static void main(String arg[]) {
String input = "a-b|c-d|e-f|g-h";
String[] primeTokens = input.split("-");
String[] level2Tokens = null;
String element = "";
String level2element = "";
ArrayList stringList = new ArrayList();
ArrayList level1List = new ArrayList();
ArrayList level2List = new ArrayList();
for (int i = 0; i < primeTokens.length; i++) {
// System.out.print(primeTokens[i]);
if (primeTokens[i].contains("|")) {
level2Tokens = primeTokens[i].split("\\|");
for (int j = 0; j < level2Tokens.length; j++) {
for (int k = 0; k < stringList.size(); k++) {
element = (String) stringList.get(k);
level2element = element + level2Tokens[j];
level2List.add(level2element);
}
}
stringList = new ArrayList();
for (int w = 0; w < level2List.size(); w++) {
stringList.add(level2List.get(w));
}
level2List = new ArrayList();
}
else {
if (stringList.size() > 0) {
for (int z = 0; z < stringList.size(); z++) {
element = (String) stringList.get(z);
element = element + primeTokens[i];
level1List.add(element);
}
stringList = new ArrayList();
for (int w = 0; w < level1List.size(); w++) {
stringList.add(level1List.get(w));
}
level1List = new ArrayList();
}
else {
element = element + primeTokens[i];
if (stringList.size() == 0) {
stringList.add(element);
}
}
}
}
for (int q = 0; q < stringList.size(); q++) {
System.out.println(stringList.get(q));
}
}
}
Input : a-b|c-d|e-f|g-h
Output:
abdfh
acdfh
abefh
acefh
abdgh
acdgh
abegh
acegh

split string and store in arraylist

I want to split the below mentioned string and save it in two seperate arraylist like state and city
public class RoundValue {
public static void main(String args[]) {
String firstset = null;
String city = "Tamilnadu;chennai-madurai-salem::Kerala;cochin-tiruvandrum-calicut";
ArrayList<String> mState = new ArrayList<String>();
ArrayList<String> mCity = new ArrayList<String>();
HashMap<String, List<String>> hashsplit = new HashMap<String, List<String>>();
List<String> splitword1 = Arrays.asList(city.split("::"));
if (splitword1.size() > 0) {
for (int i = 0; i < splitword1.size(); i++) {
firstset = splitword1.get(i);
List<String> firststate = Arrays.asList(firstset.split("-"));
if (firststate.size() > 0) {
for (int j = 0; j < firststate.size(); j++) {
String firstcity = firststate.get(j);
List<String> secondcity = Arrays.asList(firstcity.split(";"));
if (secondcity.size() > 0) {
for (int k = 0; k < secondcity.size(); k++) {
String septcity = secondcity.get(k);
System.out.println("septcity Splitted:" + septcity);
}
}
}
}
}
}
}
}
I have splitted each and every character, but i have to store state in seperate list and city in seperate list
Step 1: Split your given string input as Arrays.asList(city.split("::"));, you alresy did it.
Step 2: Split each list in to array like, example Tamilnadu;chennai-madurai-salem using String both[]=string.split(";"); here you will get seperated state and cities. like both[0] is State. both[1] is chennai-madurai-salem
Step 3: Split the cities string in both[1] usig both[1].split("-")
So Demo code I have given as below. You can modify.
public static void main(String[] args) {
String city = "Tamilnadu;chennai-madurai-salem::Kerala;cochin-tiruvandrum-calicut";
ArrayList<String> mState = new ArrayList<String>();
ArrayList<String> mCity = new ArrayList<String>();
List<String> bothList= Arrays.asList(city.split("::"));
for (String string : bothList) {
String both[]=string.split(";");
String state=both[0];
List<String> tempCityList=Arrays.asList(both[1].split("-"));
mState.add(state);
mCity.addAll(tempCityList);
}
System.out.println("Your states");
for (String string : mState) {
System.out.print(string+" ");
}
System.out.println("\nYour cities");
for (String string : mCity) {
System.out.print(string+" ");
}
}
Here is the example
import java.util.ArrayList;
import java.util.Arrays;
/**
* Created by Prasad on 6/17/2014.
*/
public class stack {
public static void main(String[] args) {
String s="Tamilnadu;chennai-madurai-salem::Kerala;cochin-tiruvandrum-calicut";
ArrayList<String> x1=new ArrayList<String>();
ArrayList<String> x2=new ArrayList<String>();
String string[]=s.split("::");
for(String y:string){
try{
String[] temp=y.split(";");
x1.add(temp[0]);
x2.add(temp[1]);
}catch(Exception e){}
}
System.out.println(x1.toString());
System.out.println(x2.toString());
}
}

Search ArrayList for certain character in string

What is the correct syntax for searching an ArrayList of strings for a single character? I want to check each string in the array for a single character.
Ultimately I want to perform multiple search and replaces on all strings in an array based on the presence of a single character in the string.
I have reviewed java-examples.com and java docs as well as several methods of searching ArrayLists. None of them do quite what I need.
P.S. Any pointers on using some sort of file library to perform multiple search and replaces would be great.
--- Edit ---
As per MightyPork's recommendations arraylist revised to use simple string type. This also made it compatible with hoosssein's solution which is included.
public void ArrayInput() {
String FileName; // set file variable
FileName = fileName.getText(); // get file name
ArrayList<String> fileContents = new ArrayList<String>(); // create arraylist
try {
BufferedReader reader = new BufferedReader(new FileReader(FileName)); // create reader
String line = null;
while ((line = reader.readLine()) != null) {
if(line.length() > 0) { // don't include blank lines
line = line.trim(); // remove whitespaces
fileContents.add(line); // add to array
}
}
for (String row : fileContents) {
System.out.println(row); // print array to cmd
}
String oldstr;
String newstr;
oldstr = "}";
newstr = "!!!!!";
for(int i = 0; i < fileContents.size(); i++) {
if(fileContents.contains(oldstr)) {
fileContents.set(i, fileContents.get(i).replace(oldstr, newstr));
}
}
for (String row : fileContents) {
System.out.println(row); // print array to cmd
}
// close file
}
catch (IOException ex) { // E.H. for try
JOptionPane.showMessageDialog(null, "File not found. Check name and directory.");
}
}
first you need to iterate the list and search for that character
string.contains("A");
for replacing the character you need to keep in mind that String is immutable and you must replace new string with old string in that list
so the code is like this
public void replace(ArrayList<String> toSearchIn,String oldstr, String newStr ){
for(int i=0;i<toSearchIn.size();i++){
if(toSearchIn.contains(oldstr)){
toSearchIn.set(i, toSearchIn.get(i).replace(oldstr, newStr));
}
}
}
For the search and replace you are better off using a dictionary, if you know that you will replace Hi with Hello. The first one is a simple search, here with the index and the string being returned in a Object[2], you will have to cast the result. It returns the first match, you were not clear on this.
public static Object[] findStringMatchingCharacter(List<String> list,
char character) {
if (list == null)
return null;
Object[] ret = new Object[2];
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
if (s.contains("" + character)) {
ret[0] = s;
ret[1] = i;
}
return ret;
}
return null;
}
public static void searchAndReplace(ArrayList<String> original,
Map<String, String> dictionary) {
if (original == null || dictionary == null)
return;
for (int i = 0; i < original.size(); i++) {
String s = original.get(i);
if (dictionary.get(s) != null)
original.set(i, dictionary.get(s));
}
}
You can try this, modify as needed:
public static ArrayList<String> findInString(String needle, List<String> haystack) {
ArrayList<String> found = new ArrayList<String>();
for(String s : haystack) {
if(s.contains(needle)) {
found.add(s);
}
}
return found;
}
(to search char, just do myChar+"" and you have string)
To add the find'n'replace functionality should now be fairly easy for you.
Here's a variant for searching String[]:
public static ArrayList<String[]> findInString(String needle, List<String[]> haystack) {
ArrayList<String[]> found = new ArrayList<String[]>();
for(String fileLines[] : haystack) {
for(String s : fileLines) {
if(s.contains(needle)) {
found.add(fileLines);
break;
}
}
}
return found;
}
You don't need to iterate over lines twice to do what you need. You can make replacement when iterating over file.
Java 8 solution
try (BufferedReader reader = Files.newBufferedReader(Paths.get("pom.xml"))) {
reader
.lines()
.filter(x -> x.length() > 0)
.map(x -> x.trim())
.map(x -> x.replace("a", "b"))
.forEach(System.out::println);
} catch (IOException e){
//handle exception
}
Another way by using iterator
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("Naman");
list.add("Aman");
list.add("Nikhil");
list.add("Adarsh");
list.add("Shiva");
list.add("Namit");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String next = iterator.next();
if (next.startsWith("Na")) {
System.out.println(next);
}
}
}

java delete reverse string in list

I have struct Array or List String like:
{ "A.B", "B.A", "A.C", "C.A" }
and I want delete reverse string from list that end of only:
{ "A.B", "A.C" }
how type String use and how delete reverse String?
To reverse a string I recommend using a StringBuffer.
String sample = "ABC";
String reversed_sample = new StringBuffer(sample).reverse().toString();
To delete object form you ArrayList use the remove method.
String sample = "ABC";String to_remove = "ADS";
ArrayList<String> list = new ArrayList<Sample>();
list.add(to_remove);list.add(sample );
list.remove(to_remove);
You can get use of a HashMap to determine whether a string is a reversed version of the other strings in the list. And you will also need a utility function for reversing a given string. Take a look at this snippets:
String[] input = { "A.B", "B.A", "A.C", "C.A" };
HashMap<String, String> map = new HashMap<String, String>();
String[] output = new String[input.length];
int index = 0;
for (int i = 0; i < input.length; i++) {
if (!map.containsKey(input[i])) {
map.put(reverse(input[i]), "default");
output[index++] = input[i];
}
}
A sample String-reversing method could be like this:
public static String reverse(String str) {
String output = "";
int size = str.length();
for (int i = size - 1; i >= 0; i--)
output += str.charAt(i) + "";
return output;
}
Output:
The output array will contain these elements => [A.B, A.C, null, null]
A code is worth thousand words.....
public class Tes {
public static void main(String[] args) {
ArrayList<String> arr = new ArrayList<String>();
arr.add("A.B");
arr.add("B.A");
arr.add("A.C");
arr.add("C.A");
System.out.println(arr);
for (int i = 0; i < arr.size(); i++) {
StringBuilder str = new StringBuilder(arr.get(i));
String revStr = str.reverse().toString();
if (arr.contains(revStr)) {
arr.remove(i);
}
}
System.out.println(arr);
}
}
You can do this very simply in O(n^2) time. Psuedocode:
For every element1 in the list:
For every element2 in the list after element1:
if reverse(element2).equals(element1)
list.remove(element2)
In order to make your life easier and prevent ConcurrentModificationException use Iterator. I won't give you the code because it's a good example to learn how to properly use iterators in Java.
Reverse method:
public String reverse(String toReverse) {
return new StringBuilder(toReverse).reverse().toString();
}
Edit: another reverse method:
public String reverse(String toReverse) {
if (toReverse != null && !toReverse.isEmpty) {
String[] elems = toReverse.split(".");
}
StringBuilder reversedString = new StringBuilder("");
for (int i = elems.length - 1; i >= 0; i++) {
reversedString.append(elems[i]);
reversedString.append(".");
}
return reversedString.toString();
}
Check this
public static void main(String arg[]){
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
List<String> strList = new ArrayList<String>();
strList.add("A.B");
strList.add("B.A");
strList.add("A.C");
strList.add("C.A");
Iterator<String> itr = strList.iterator();
while(itr.hasNext()){
String [] split = itr.next().toUpperCase().split("\\.");
if(str.indexOf(split[0])>str.indexOf(split[1])){
itr.remove();
}
}
System.out.println(strList);
}
output is
[A.B, A.C]
You can iterate the list while maintaining a Set<String> of elements in it.
While you do it - create a new list (which will be the output) and:
if (!set.contains(current.reverse())) {
outputList.append(current)
set.add(current)
}
This solution is O(n*|S|) on average, where n is the number of elements and |S| is the average string length.
Java Code:
private static String reverse(String s) {
StringBuilder sb = new StringBuilder();
for (int i = s.length()-1 ; i >=0 ; i--) {
sb.append(s.charAt(i));
}
return sb.toString();
}
private static List<String> removeReverses(List<String> arr) {
Set<String> set = new HashSet<String>();
List<String> res = new ArrayList<String>();
for (String s : arr) {
if (!set.contains(reverse(s))) {
res.add(s);
set.add(s);
}
}
return res;
}
public static void main(String[]args){
String[] arr = { "a.c" , "b.c", "c.a", "c.b" };
System.out.println(removeReverses(arr));
}
will yield:
[a.c, b.c]

Categories