given a word, print its index, words can be increased accordingly

前端 未结 5 1610
南方客
南方客 2021-02-04 06:26

Imagine an alphabet of words.

Example:

 a ==> 1 
 b ==> 2 
 c ==> 3 

 z ==> 26 
 ab ==> 27 
 ac ==> 28 

 az ==> 51 
 bc ==> 52         


        
5条回答
  •  眼角桃花
    2021-02-04 06:55

    For letters of this imaginary alphabet that are more than one character long, we may use the recursion:

    XnXn-1..X1 = 
      max(n-1) 
          + (max(n-1) - last (n-1)-character letter before 
                        the first (n-1)-character letter after a)
      ... + (max(n-1) - last (n-1)-character letter before the
                        first (n-1)-character letter after the-letter-before-Xn)
      + 1 + ((Xn-1..X1) - first (n-1)-character letter after Xn)
    
    where max(1) = z, max(2) = yz...
    

    Haskell code:

    import Data.List (sort)
    import qualified Data.MemoCombinators as M
    
    firstAfter letter numChars = take numChars $ tail [letter..]
    
    lastBefore letter numChars = [toEnum (fromEnum letter - 1) :: Char] 
                              ++ reverse (take (numChars - 1) ['z','y'..])
    
    max' numChars = reverse (take numChars ['z','y'..])
    
    loop letter numChars = 
      foldr (\a b -> b 
                     + index (max' numChars) 
                     - index (lastBefore (head $ firstAfter a numChars) numChars)
            ) 0 ['a'..letter]
    
    index = M.list M.char index' where
      index' letter
        | null (drop 1 letter)  = fromEnum (head letter) - 96
        | letter /= sort letter = 0
        | otherwise = index (max' (len - 1))
                    + loop (head $ lastBefore xn 1) (len - 1)
                    + 1
                    + index (tail letter) - index (firstAfter xn (len - 1))
       where len = length letter
             xn = head letter
    

    Output:

    *Main> index "abcde"
    17902
    
    *Main> index "abcdefghijklmnopqrstuvwxyz"
    67108863
    (0.39 secs, 77666880 bytes)
    

提交回复
热议问题