Comment comparer ces deux chaînes:
def matchPattern(a:String, b: String):String= { val dd = a.split(" ") val result = dd.map(_.toLowerCase()) if(result contains b.toLowerCase) true else false }
un autre exemple
val a = "vegan protein powder" val b = "vega"
un autre exemple
val a = "hero 6 go pro" val b = "gopro"
4 Réponses :
Quelque chose comme ça je suppose (vos exigences sont incomplètes, donc je les ai interprétées comme "correspondant exactement à la partie de début de la chaîne donnée, se terminant par un espace ou une fin de ligne, sauf peut-être des espaces).
@tailrec def matchWords(input: Seq[Char], words: Seq[Char]): Boolean = (input, words) match { case (Seq(), Seq() | Seq(' ', _*)) => true case (Seq(), _) => false case (Seq(a, tail@_*), Seq(b, rest@_*)) if a == b => matchWords(tail, rest) case (_, Seq(' ', rest@_*)) => matchWords(input, rest) case _ => false }
Voici une approche utilisant glissant (i)
, où i
va de 2 au nombre de mots dans a
, pour assembler une liste de tous les mots adjacents concaténés possibles. Il est ensuite vérifié pour voir si b
correspond exactement à l'un des éléments de la liste, comme indiqué ci-dessous:
def matchPattern(a: String, b: String): Boolean = { val words = a.toLowerCase.split("\\s+") val concats = (2 to words.size).foldLeft(words)( (acc, i) => acc ++ words.sliding(i).map(_.mkString) ) concats contains b.toLowerCase } matchPattern("Hero go Pro 6", "gopro") // res1: Boolean = true matchPattern("Hero go Pro 6", "gopro6") // res2: Boolean = true matchPattern("Vegan protein powder", "vega") // res3: Boolean = false
Je pense que c'est une solution à votre problème.
def matchPattern(a: String, b: String): Boolean = a .split("\\s+") .tails .flatMap(_.inits) .exists(_.mkString("") == b)
Cela vérifiera tout mot ou séquence de mots dans a
qui correspond exactement au mot de b . Il rejettera les cas où b
est incorporé dans un mot plus long ou une séquence de mots.
L'appel split
transforme la chaîne en une liste de mots.
L'appel tails
renvoie toutes les sous-séquences de fin possibles d'une liste, et inits
renvoie toutes les sous-séquences de début. La combinaison des deux génère toutes les sous-séquences possibles de la liste d'origine.
L'appel exist
joint les mots ensemble et les compare avec le mot de test.
Notez que tails
et inits
sont paresseux, ils vont donc générer chaque solution à tester à tour de rôle, et s'arrêter dès qu'une solution est trouvée. Cela contraste avec les solutions utilisant le glissant
qui créent toutes les combinaisons possibles avant de les vérifier.
Voici une approche utilisant pour / yield
qui s'est avérée similaire à l'approche @ leo-c. Un pour
est utilisé pour générer une fenêtre glissante de longueur i
à partir de mots
pour renvoyer les mots et combinaisons d'origine.
val a = "fit bit versa" val b = "fitbit" val c = "go pro hero 6" val d = "gopro" val e = "hero go pro 6" val f = "gopro" //false val g = "vegan protein powder" val h = "vega" val i = "foo gopro bar" val j = "gopro" val k = "foo go pro hero bar" val l = "goprohero" scala> matchPattern(a,b) && matchPattern(c,d) && matchPattern(e,f) && !matchPattern(g,h) && matchPattern(i,j) && matchPattern(k,l) res175: Boolean = true
Scénarios de test:
def matchPattern(a:String, b: String): Boolean = { val words = a.split(" ") val combinations = words ++ (for( i <- (2 to words.size); acc <- words.sliding(i) ) yield acc).map(_.mkString) combinations.contains(b) }
Qu'en est-il de
val a = "foo gopro bar"; val b = "gopro"
etval a = "foo go pro hero bar"; val b = "goprohero
?Ouais ... tout cela devrait être vrai
\ bf \ s * i \ s * t \ s * b \ s * i \ s * t \ b
et\ bg \ s * o \ s * p \ s * r \ s * o \ b
et\ bv \ s * e \ s * g \ s * a \ b
où les expressions rationnelles sont insensibles à la casse.@sln Je pense que l'OP recherche une fonction générique
matchPattern
, pas quelques expressions régulières pour ce cas particulier. Ce serait bien si le PO expliquait plus clairement les règles du test.@Tim - Evidemment, l'expression régulière est générée en mettant
\ s *
entre chaque caractère et en bookending avec les\ b
.@sln Le code pour cela peut ne pas être évident pour tout le monde, alors peut-être pourriez-vous le partager avec nous? Vous pouvez inclure une version curry de
matchPattern
qui est plus efficace lors de la vérification du même mot dans plusieurs chaînes.