Bonjour les amis! J'essaie de créer un programme qui détecte si plusieurs mots sont dans une chaîne aussi rapidement que possible, et si c'est le cas, exécute un comportement. De préférence, je voudrais qu'il détecte également l'ordre de ces mots, mais seulement si cela peut être fait rapidement. Jusqu'à présent, voici ce que j'ai fait:
if (input.contains("adsf") && input.contains("qwer")) {
execute();
}
Comme vous pouvez le voir, le faire pour plusieurs mots deviendrait fastidieux. Est-ce le seul moyen ou existe-t-il un meilleur moyen de détecter plusieurs sous-chaînes? Et existe-t-il un moyen de détecter l'ordre?
Vous pouvez utiliser un tableau:
String[] matches = new String[] {"adsf", "qwer"};
bool found = false;
for (String s : matches)
{
if (input.contains(s))
{
execute();
break;
}
}
C'est aussi efficace que celui que vous avez publié mais plus facile à maintenir. La recherche d'une solution plus efficace ressemble à une micro-optimisation qui doit être ignorée jusqu'à ce qu'il soit prouvé qu'elle est effectivement un goulot d'étranglement de votre code, dans tous les cas avec un énorme jeu de chaînes, la solution pourrait être un trie.
Je créerais une expression régulière à partir des mots:
Pattern pattern = Pattern.compile("(?=.*adsf)(?=.*qwer)");
if (pattern.matcher(input).find()) {
execute();
}
Pour plus de détails, consultez cette réponse: https://stackoverflow.com/a/470602/66014
Dans Java 8 vous pourriez faire,
String[] searchFor= {"asdf", "qwer"};
String input = "asdf qwer";
public static boolean containsItemFromArray(String inputString, String[] items) {
return Arrays.stream(input).allMatch(searchFor::contains);
}
Si vous avez beaucoup de sous-chaînes à rechercher, alors une expression régulière ne va probablement pas être très utile, donc vous feriez mieux de mettre les sous-chaînes dans une liste, puis de les itérer et d'appeler input.indexOf(substring)
sur chacun. Cela renvoie un index int
de l'endroit où la sous-chaîne a été trouvée. Si vous jetez chaque résultat (sauf -1, ce qui signifie que la sous-chaîne n'a pas été trouvée) dans un TreeMap
(où index
est la clé et la sous-chaîne est la valeur), alors vous pouvez récupérez-les dans l'ordre en appelant keys()
sur la carte.
Map<Integer, String> substringIndices = new TreeMap<Integer, String>();
List<String> substrings = new ArrayList<String>();
substrings.add("asdf");
// etc.
for (String substring : substrings) {
int index = input.indexOf(substring);
if (index != -1) {
substringIndices.put(index, substring);
}
}
for (Integer index : substringIndices.keys()) {
System.out.println(substringIndices.get(index));
}
Utilisez une structure arborescente pour contenir les sous-chaînes par point de code. Cela élimine le besoin de
Notez que cela n'est efficace que si le jeu d'aiguilles est presque constant. Cependant, il n'est pas inefficace s'il y a des ajouts ou des suppressions de sous-chaînes individuelles, mais une initialisation différente à chaque fois pour organiser un grand nombre de chaînes dans une arborescence la ralentirait certainement.
StringSearcher
:import Java.util.ArrayList;
import Java.util.Collections;
import Java.util.List;
import Java.util.Map;
import Java.util.HashMap;
class StringSearcher{
private NeedleTree needles = new NeedleTree(-1);
private boolean caseSensitive;
private List<Integer> lengths = new ArrayList<>();
private int maxLength;
public StringSearcher(List<String> inputs, boolean caseSensitive){
this.caseSensitive = caseSensitive;
for(String input : inputs){
if(!lengths.contains(input.length())){
lengths.add(input.length());
}
NeedleTree tree = needles;
for(int i = 0; i < input.length(); i++){
tree = tree.child(caseSensitive ? input.codePointat(i) : Character.toLowerCase(input.codePointAt(i)));
}
tree.markSelfSet();
}
maxLength = Collections.max(legnths);
}
public boolean matches(String haystack){
if(!caseSensitive){
haystack = haystack.toLowerCase();
}
for(int i = 0; i < haystack.length(); i++){
String substring = haystack.substring(i, i + maxLength); // maybe we can even skip this and use from haystack directly?
NeedleTree tree = needles;
for(int j = 0; j < substring.maxLength; j++){
tree = tree.childOrNull(substring.codePointAt(j));
if(tree == null){
break;
}
if(tree.isSelfSet()){
return true;
}
}
}
return false;
}
}
NeedleTree.Java
:import Java.util.HashMap;
import Java.util.Map;
class NeedleTree{
private int codePoint;
private boolean selfSet;
private Map<Integer, NeedleTree> children = new HashMap<>();
public NeedleTree(int codePoint){
this.codePoint = codePoint;
}
public NeedleTree childOrNull(int codePoint){
return children.get(codePoint);
}
public NeedleTree child(int codePoint){
NeedleTree child = children.get(codePoint);
if(child == null){
child = children.put(codePoint, new NeedleTree(codePoint));
}
return child;
}
public boolean isSelfSet(){
return selfSet;
}
public void markSelfSet(){
selfSet = true;
}
}
Je pense qu'une meilleure approche serait quelque chose comme ça, où nous pouvons ajouter plusieurs valeurs en une seule chaîne et par index de fonction, valider index
String s = "123";
System.out.println(s.indexOf("1")); // 0
System.out.println(s.indexOf("2")); // 1
System.out.println(s.indexOf("5")); // -1
Il s'agit d'un entretien classique et d'un problème CS.
L'algorithme de Robin Karp est généralement ce dont les gens parlent en premier lors des entretiens. L'idée de base est que lorsque vous parcourez la chaîne, vous ajoutez le caractère actuel au hachage. Si le hachage correspond au hachage d'une de vos chaînes de correspondance, vous savez que vous pouvez avoir une correspondance. Cela évite d'avoir à balayer d'avant en arrière dans vos chaînes de correspondance. https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm
D'autres sujets typiques pour cette question d'entrevue sont d'envisager une structure de tri pour accélérer la recherche. Si vous avez un grand ensemble de chaînes de correspondance, vous devez toujours vérifier un grand ensemble de chaînes de correspondance. Une structure de trie est plus efficace pour effectuer cette vérification. https://en.wikipedia.org/wiki/Trie
Les algorithmes supplémentaires sont: - Aho – Corasick https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_algorithm - Commentz-Walter https: //en.wikipedia. org/wiki/Commentz-Walter_algorithm