Tâche
La tâche consiste à jouer au golf un algorithme de correspondance de chaîne exacte en temps réel de votre choix.
Contribution
Deux lignes de texte fournies sur l'entrée standard, séparées par une nouvelle ligne. La première ligne contient le "motif" et sera simplement une chaîne ASCII tirée des lettres a-z
.
La deuxième ligne contient le "texte" plus long et sera également simplement une chaîne ASCII tirée des lettres a-z
.
Production
Une liste d'indices d'où les correspondances exactes se produisent. Vous devez afficher la position du début de chaque correspondance qui se produit.
spécification
Votre algorithme peut passer du temps linéaire à prétraiter le modèle. Il doit ensuite lire le texte de gauche à droite et prendre un temps constant pour chaque caractère du texte et afficher toute nouvelle correspondance dès qu'elle se produit. Les matchs peuvent bien sûr se chevaucher.
Algorithme
Il existe de nombreux algorithmes de correspondance exacte en temps réel. Un est mentionné sur le wiki pour KMP par exemple. Vous pouvez utiliser celui que vous aimez, mais vous devez toujours fournir la bonne réponse.
Je garderai un tableau des leaders linguistiques pour que ceux qui préfèrent les langues populaires puissent aussi gagner à leur manière. Veuillez expliquer quel algorithme vous avez implémenté.
Temps réel
Il semble qu'il y ait eu beaucoup de confusion sur ce que signifie en temps réel. Cela ne signifie pas simplement un temps linéaire. Le KMP standard n'est donc pas en temps réel. Le lien dans la question pointe explicitement vers une partie de la page wiki pour KMP sur une variante en temps réel de KMP. Boyer-Moore-Galil n'est pas non plus en temps réel. Cette question / réponse de cstoryory discute le problème ou on peut simplement google "correspondance exacte en temps réel" ou des termes similaires.
la source
abcd
etacbdefg
, je produirais1 4
, poura
etd
?a
et led
match. Il y aabcd
etacbdefg
, et lea
etd
sont à des positions identiques.Réponses:
Python 2, 495 octets
Celui-ci est un KMP en temps réel, qui est beaucoup plus court et seulement légèrement plus lent que l'algorithme BMG (qui est généralement sublinéaire). Appelez avec
K(pattern, text)
; la sortie est identique à l'algorithme BMG.la source
Python 2, 937 octets
Ce n'est pas court, en aucun cas, mais cela (a) fonctionne, (b) satisfait à toutes les exigences, et (c) est joué au golf autant que je peux le faire.
Il s'agit d'une implémentation de l'algorithme de Boyer-Moore-Galil. Assez simple - appelez avec
S(pattern,text)
; les deux autres fonctions sont utilisées dans le prétraitement. En effet, tout sauf les 5 dernières lignes est un prétraitement.Un exemple d'exécution, qui a pris environ une seconde:
la source
O(m)
prétraitement et enO(n)
correspondance [=>O(n+m)
], ce que cela fait (ou mieux).O(n+m)
temps, mais prendre n temps pour l'un des symboles du texte, par exemple.KMP, Python 2 (213 octets)
Version non golfée. La première boucle consiste à construire les automates KMP. La deuxième boucle marche sur les automates. Ils partagent presque le même modèle, mais les résumer coûtera plus d'octets, donc pour un golf de code, je préfère dupliquer cette logique. Une implémentation similaire est en fait largement utilisée dans la programmation des concours.
la source
KMP en temps réel, Python 2 (167 octets)
Dans KMP normal, nous simulons le comportement de l'automate en utilisant une fonction d'échec. Dans ce KMP en temps réel, l'automate complet est construit de sorte que dans la phrase correspondante, il puisse traiter chaque caractère en temps réel (temps constant).
La complexité temporelle et spatiale du prétraitement est O (nm), où m est la taille de l'alphabet et n est la longueur de la chaîne de motif. Cependant, dans mes tests, la taille réelle de la table de transition est toujours inférieure à 2n, donc nous pouvons peut-être prouver que la complexité temporelle et spatiale est O (n).
Version non golfée
la source
Q, 146 octets
Tester
génère 15 et 34
Remarques
Non limité à l'alphabet (prend en charge tous les caractères ascii et respecte la casse).
N'utilise aucune des opérations spécifiques définies par Q sur les chaînes -> fonctionne sur les chaînes en tant que séquences (correspondance des opérations, longueur, etc.)
Minimise la table de transition joignant tous les caractères qui ne sont pas dans le modèle en une seule classe de caractères unique.
Je peux presser un peu le code. C'est une première tentative pour valider la stratégie de la solution
Visitez n'importe quel caractère du texte une seule fois, et pour chaque caractère saisi, il y a un saut unique. Je suppose donc que la recherche correspond au «temps réel»
La construction de la table al état i et char c recherche la sous-chaîne la plus longue qui se termine en i et après l'ajout de c est un préfixe de S. La construction n'est pas optimisée, donc je ne sais pas si elle est valide
Le format d'entrée ne correspond pas bien à la langue. La transmission de deux arguments de chaîne permettra d'économiser 16 octets
Explication
global W représente le motif et S correspond au texte à rechercher
x:1_"\n "\:x
code bizarre pour faire face aux exigences d'entrée (Q nécessite que les chaînes multilignes aient des non-premières lignes en retrait, donc il doit éliminer l'espace supplémentaire devant chaque non-première ligne)n::#W
calcule la longueur et enregistre en tant que n globalu::?W
calcule des caractères uniques en W et enregistre comme u globalu?S
génère la classe charactée pour chaque caractère de SConstruisez une table de transition T avec une ligne par caractère unique en W (plus un supplémentaire) et une colonne pour chaque index en W (plus un supplémentaire). La ligne supplémentaire correspond à l'état initial et la colonne supplémentaire collecte tout caractère en S mais pas en W. Cette stratégie minimise la taille de la table
p:{$[n<#x;0;x~(#x)#W;#x;0]}
est la fonction qui recherche le préfixe le plus longf:{{|/p'x}'((1_)\x#W),\:/:u}
est la fonction qui calcule une ligne x de TRechercher du texte à l'aide de la table de transition.
T\[0;u?S]
itère sur 0 (état initial) et chacune des classes de caractères de S, en utilisant comme nouvelle valeur la valeur de la table de transition T [état] [charClass]. Les états finaux ont la valeur n, nous recherchons donc cette valeur dans la séquence d'états et la renvoyons ajustée (pour indiquer la position initiale au lieu de la position finale de chaque correspondance)la source
Boyer-Moore, Perl (50)
Perl essaie d'utiliser Boyer-Moore naturellement:
la source