I want to check if the target string contains string in collections. And match the longest one. E.g.
Target string: str = "eignelaiwgn"
Collection strings: eig, a, eb, eigne, eignep
The result needs to be eigne
First I thought HashMap, but it is not sorted. So I try to put collection strings into ArrayList, then sort the list with string length. Then use for each loop to check
if ( str.contains("eigne") )
This needs to loop list each time. Is there a better(faster) way to achieve this?
Seems pretty straightforward with streams:
String targetString = "eignelaiwgn";
Collection<String> collection = Arrays.asList("eig", "a", "eb", "eigne", "eignep");
Optional<String> longestMatch = collection.stream()
.filter(targetString::contains)
.max(Comparator.comparingInt(String::length));
longestMatch.ifPresent(System.out::println); // eigne
This reads as: For every string in the collection, check if the target string contains it. If true, return the string with the max length. (As the collection might be empty, or as no string in the collection might match the filter, max returns an Optional<String>).
You could use a TreeSet for the same.
String str = "eignelaiwgn";
// Assuming that the 'sub-strings' are stored in a list
List<String> myList = Arrays.asList("eig", "a", "eb", "eigne", "eignep");
// Create a TreeSet that sorts based on descending order of length
Set<String> treeSet = new TreeSet<>((a, b) -> b.length() - a.length());
treeSet.addAll(myList);
String containsSub = treeSet.stream().filter(e -> str.contains(e))
.findFirst()
.orElse("Not found");
Now we iterate over the TreeSet and find the first occurrence where the sub-string is present in the original string. Now since the TreeSet is sorted in descending order of length, iteration will start from the highest to the lowest.
you can use LevensteinDistance() method of StringUtils class in java which will tell you the number of changes needed to change one String into another.you can print string with minimum changes needed, which is your answer. see this document -> LevenshteinDistance
Also look for differences method for same class which will tell the difference between the two string.
You could use a suffix tree. Please follow this link:
https://www.geeksforgeeks.org/pattern-searching-using-suffix-tree/
Related
Hey guys I have been having trouble removing duplicate letters from a string. I have tried for loops using string methods but I dont seen to be getting anywhere. Does anyone know how to either remove duplicate letters from either a linked list or a string. I have a String sent which holds a a a c d e e k o r t. I also have a LinkedList word = new Linked List(); which has the same letters.
By utilizing the properties of a LinkedHashSet, which guarantees uniqueness among its elements and preserves order:
String string = "foobar";
Set<Character> uniqueChars = new LinkedHashSet<>();
for (char character : string.toCharArray()) {
uniqueChars.add(character );
}
uniqueChars.forEach(character -> System.out.print(character)); // fobar
A more advanced alternative is to make use of Java 8 Stream API, which will accomplish the same:
String string = "foobar";
LinkedHashSet<Character> uniqueChars = string.chars()
.mapToObj(character -> (char) character )
.collect(Collectors.toCollection(LinkedHashSet::new));
uniqueChars.forEach(character -> System.out.print(character)); //fobar
there are 2-3 ways to achieve the same like below:
Try to put value in SET
new HashSet<>(listWithDuplicates)
The same can be done using Guava as well:
Lists.newArrayList(Sets.newHashSet(listWithDuplicates));
Finally – let’s look at a new solution, using Lambdas in Java 8; we’re going to use the distinct() method from the Stream API which returns a stream consisting of distinct elements based on the result returned by equals() method:
listWithDuplicates.stream()
.distinct()
.collect(Collectors.toList());
Please let me know if it helps..
for Stream api details and example please follow below URL:
https://kpblogs.com/java/java8/java-stream-api-with-example/
I am trying to sort via alphabetical order,
I pasted my code snippet below and the issue I'm having.
String[] arr = new String[3];
arr[0] = config.getfoldersdata() + "." + config.getCars();
arr[1] = config.getType();
arr[2] = entry.getVals() ? "Data" : "Entry";
result.add(arr);
I want to sort alphabetically the .getCars.
The above code returns arr 1-3 in a single line/row. There can be multiple records/rows/line. So I want them to be sorted alphabetically, by what is returned by .getCars.
The .getCars will return a string.
I have tried the Arrays.sort() above, but the re is no change in the result (no sorting).
Where am I going wrong ?
Your design is awful: the arrays should in fact be objects.
But anyway, you just need a comparator which sorts the array based on their first element's natural ordering:
result.sort(Comparator.comparing(array -> array[0]));
as far as i know u can't sort in alphabetical order using normal arrays try using tree set like this TreeSet tree = new TreeSet(); that way it will be sorted in
I got array of String hash values, for example: "123-51s-12as-dasd1-das-41c-sadasdgt-31". I need to find out if there are any duplicates. The catch is, that I need to find them all in O(nlogn).
1) My idea:
To do this I could use binary-search algorithm. But binary-search works only for sorted numeric array. So I ask: Is there any way to sort string array ?
2) I am open for any other answers. My question is:
How to find all duplicates in array of unknown strings - nlogn.
Since the time bound is nlog(n), you could safely first sort the array, and then do a scan from left to right to check for duplicated strings.
You can use a Set<String> and insert your strings into it by cycling the array: walking the array is O(n), inserting is O(log(n)). If .add() returns false, this is a duplicate:
public Set<String> getDups(String[] hashes)
{
Set<String> all = new HashSet<String>();
Set<String> ret = new HashSet<String>();
for (final String hash: hashes)
if (!all.add(hash)) // already seen
ret.add(hash);
return ret;
}
This question already has answers here:
Java: Get first item from a collection
(14 answers)
Closed 4 years ago.
I'd like to know if I can get the first element of a list or set. Which method to use?
See the javadoc
of List
list.get(0);
or Set
set.iterator().next();
and check the size before using the above methods by invoking isEmpty()
!list_or_set.isEmpty()
Collection c;
Iterator iter = c.iterator();
Object first = iter.next();
(This is the closest you'll get to having the "first" element of a Set. You should realize that it has absolutely no meaning for most implementations of Set. This may have meaning for LinkedHashSet and TreeSet, but not for HashSet.)
In Java >=8 you could also use the Streaming API:
Optional<String> first = set.stream().findFirst();
(Useful if the Set/List may be empty.)
Let's assume that you have a List<String> strings that you want the first item from.
There are several ways to do that:
Java (pre-8):
String firstElement = null;
if (!strings.isEmpty() && strings.size() > 0) {
firstElement = strings.get(0);
}
Java 8:
Optional<String> firstElement = strings.stream().findFirst();
Guava
String firstElement = Iterables.getFirst(strings, null);
Apache commons (4+)
String firstElement = (String) IteratorUtils.get(strings, 0);
Apache commons (before 4)
String firstElement = (String) CollectionUtils.get(strings, 0);
Followed by or encapsulated within the appropriate checks or try-catch blocks.
Kotlin:
In Kotlin both Arrays and most of the Collections (eg: List) have a first method call.
So your code would look something like this
for a List:
val stringsList: List<String?> = listOf("a", "b", null)
val first: String? = stringsList.first()
for an Array:
val stringArray: Array<String?> = arrayOf("a", "b", null)
val first: String? = stringArray.first()
Followed by or encapsulated within the appropriate checks or try-catch blocks.
Kotlin also includes safer ways to do that for kotlin.collections, for example firstOrNull or getOrElse, or getOrDefault when using JRE8
I'm surprised that nobody suggested guava solution yet:
com.google.common.collect.Iterables.get(collection, 0)
// or
com.google.common.collect.Iterables.get(collection, 0, defaultValue)
// or
com.google.common.collect.Iterables.getFirst(collection, defaultValue)
or if you expect single element:
com.google.common.collect.Iterables.getOnlyElement(collection, defaultValue)
// or
com.google.common.collect.Iterables.getOnlyElement(collection)
java8 and further
Set<String> set = new TreeSet<>();
set.add("2");
set.add("1");
set.add("3");
String first = set.stream().findFirst().get();
This will help you retrieve the first element of the list or set.
Given that the set or list is not empty (get() on empty optional will throw java.util.NoSuchElementException)
orElse() can be used as: (this is just a work around - not recommended)
String first = set.stream().findFirst().orElse("");
set.removeIf(String::isEmpty);
Below is the appropriate approach :
Optional<String> firstString = set.stream().findFirst();
if(firstString.isPresent()){
String first = firstString.get();
}
Similarly first element of the list can be retrieved.
Hope this helps.
Set
set.toArray()[0];
List
list.get(0);
This is not an exact answer to this question, but in case the objects should be sorted SortedSet has a first() method:
SortedSet<String> sortedSet = new TreeSet<String>();
sortedSet.add("2");
sortedSet.add("1");
sortedSet.add("3");
String first = sortedSet.first(); //first="1"
The sorted objects must implement the Comparable interface (like String does)
You can use the get(index) method to access an element from a List.
Sets, by definition, simply contain elements and have no particular order. Therefore, there is no "first" element you can get, but it is possible to iterate through it using iterator (using the for each loop) or convert it to an array using the toArray() method.
I have an arraylist<string> of words. I sort it using Collections.sort(wordsList);
I'm using this array for an auto-suggest drop down box, so that when the user is typing in a letter, they are given a list of suggestions similar to what they are typing in.
How do I go about searching this array for a prefix of string, say the user types in "mount" and the array contains the word "mountain", how can I search this array and return similar values.
Here's my code so far:
public List<Interface> returnSuggestedList(String prefix) {
String tempPrefix = prefix;
suggestedPhrases.clear();
//suggestedPhrases = new ArrayList<Interface>();
//Vector<String> list = new Vector<String>();
//List<Interface> interfaceList = new ArrayList<Interface>();
Collections.sort(wordsList);
System.out.println("Sorted Vector contains : " + wordsList);
int i = 0;
while (i != wordsList.size()) {
int index = Collections.binarySearch(wordsList, prefix);
String tempArrayString = wordsList.get(index).toString();
if (tempArrayString.toLowerCase().startsWith(prefix.toLowerCase())) {
ItemInterface itemInt = new Item(tempArrayString);
suggestedPhrases.add(itemInt);
System.out.println(suggestedPhrases.get(i).toString());
System.out.println("Element found at : " + index);
}
i++;
}
return suggestedPhrases;
}
The most basic approach would be
List<String> result = new ArrayList<String>();
for(String str: words){
if(str.contains(keyword){
result.add(str);
}
}
You can improve this version, if you only concern with startWith instead of contains then you can distribute words in a HashMap and you will have narrowed search
For this task, there are better data structures than a sorted array of strings. You might look e.g. at DAWG (Directed acyclic word graph).
If wordList is fixed (does not change from one method call to the other) you should sort it somewhere else, because sort is costly, and store it in lowercase.
In the rest of the method you would do something like:
List<String> selected = new ArrayList<String>();
for(String w:wordList){
if(w.startsWith(prefix.toLower())) // or .contains(), depending on
selected.add(w); // what you want exactly
}
return selected;
Also see the trie data structure. This question has useful info. I should think its getPrefixedBy() will be more efficient than anything you can roll by hand quickly.
Of course, this will work for prefix searches only. Contains search is a different beast altogether.
As #Jiri says you can use a DAWG, but if you don't want to go that far you can do some simple and useful things.
Make use of the sorting
If you want to sort the array of words do it previously. don't sort it each time
As it's sorted you can find the first and the last word in the list that are matches. The use list.subList(from, to) to return sublist. It's a little more optimal that adding each one.
Use a pre-sorted structure
Use a TreeSet<String> for storing the strings (the will be sorted internally).
Then use treeSet.subSet(from, true, to, false);
Where from is the prefix and to is the "prefix plus one char". By example if you're looking for abc, to must be abd. If you don't want to make that char transformation anyway you can ask for treeSet.headSet(from) and iterate over it until there are no more prefixes.
This is specially useful if you read more than you write. Maybe ordering strings is a little expensive but once ordered you can find them very fast (O(log n)).
Case insensitive comparing
You can provide a Comparator<String> to the tree set in order to indicate how it must order the strings. You cam implement it or maybe there are a prebuild case-insensitive comparator over there.
Anyway its code should be:
int compare(String a, String b) {
return a.toLowerCase().compareTo(b.toLowerCase());
}
Here is a similar example:
-> http://samuelsjoberg.com/archive/2009/10/autocompletion-in-swing