How to compare a string with another where the one has space in between

后端 未结 4 1256
挽巷
挽巷 2021-01-13 05:04

How do I compare these two string :

val a = \"fit bit versa\"
val b = \"fitbit\"

another example

val a = \"go pro hero 6\"
         


        
相关标签:
4条回答
  • 2021-01-13 05:28

    Here's one approach using sliding(i), where i ranges from 2 to word-count in a, to assemble a list of all possible concatenated adjacent words. It is then checked to see whether b exactly matches any of the elements in the list, as shown below:

    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
    
    0 讨论(0)
  • 2021-01-13 05:30

    I think this is a solution to your problem.

    def matchPattern(a: String, b: String): Boolean =
      a
        .split("\\s+")
        .tails
        .flatMap(_.inits)
        .exists(_.mkString("") == b)
    

    This will check for any word or sequence of words in a that exactly matches the word in b. It will reject cases where b is embedded in a longer word or sequence of words.

    The split call turns the string into a list of words.

    The tails call returns all the possible trailing sub-sequences of a list, and inits returns all the leading sub-sequences. Combining the two generates all possible sub-sequences of the original list.

    The exist call joins the words together and compares them with the test word.


    Note that tails and inits are lazy, so they will generate each solution to be tested in turn, and stop as soon as a solution is found. This is in contrast to the solutions using sliding which create every possible combination before checking any of them.

    0 讨论(0)
  • 2021-01-13 05:41

    Something like this I guess (your requirements are incomplete, so I interpreted them to "match exactly the beginning portion of the given string, ending with whitespace or end of line, except maybe spaces).

      @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
       }
    
    0 讨论(0)
  • 2021-01-13 05:43

    Here's an approach using for/yield that turned out similar to @leo-c approach. A for is used to generate a sliding window of length i from words to return the original words and combinations.

    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)
    } 
    

    Test cases:

    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
    
    0 讨论(0)
提交回复
热议问题