仅在两个字符连续的情况下,才能找到在列表中是否找到两个字符的序列的方法吗?

问题描述

我目前正在使用elm语法。一个例子是这样的:

(序列('a')('b'))('c')['a','b','c','d']。在此示例中,我仅测试元素“ a”,“ b”,“ c”是否为列表的成员。如果是,那么我将其分区并获得(['a','b','c'],['d'])

在以下情况下,我遇到了问题

 (Sequence ('a') ('b')) ('c') ['a','b','c','a']

获得结果: (['a','b','c','a'],[])

我的问题是:我应该放置什么条件,以使元素“ a”和“ b”必须连续,以避免出现这种情况当它们单独匹配时?

解决方法

下面是一些代码,用于测试列表中是否出现元素序列:

module Main exposing (main)
 
import Html exposing (Html,text)


containsSeq : List a -> List a -> Bool
containsSeq seq list =
    let
        helper remainingSeq remainingList savedSeq savedList =
            case remainingSeq of
                [] ->
                    True

                x :: xs ->
                    case remainingList of
                        [] ->
                            False

                        y :: ys ->
                            if x == y then
                                helper xs ys (savedSeq ++ [ x ]) (savedList ++ [ y ])

                            else
                                case savedList of
                                    [] ->
                                        helper (savedSeq ++ remainingSeq) ys [] []

                                    y2 :: y2s ->
                                        helper (savedSeq ++ remainingSeq) (y2s ++ remainingList) [] []
    in
    helper seq list [] []


main =
    text <| Debug.toString <| containsSeq [ 'a','b','c' ] [ 'a','a','c','d' ]

这仅检查序列是否出现以及元素的类型必须为comparable

这是对上述函数的更改,以将旧列表的分区返回为3个元素元组,其元素为(elementsBefore,sequence,elementsAfter)。结果包装在Maybe中,因此,如果找不到该序列,则返回Nothing

module Main exposing (main)

import Html exposing (Html,text)


partitionBySeq : List a -> List a -> Maybe ( List a,List a,List a )
partitionBySeq seq list =
    let
        helper remainingSeq remainingList savedSeq savedCurrentList savedOldList =
            case remainingSeq of
                [] ->
                    Just ( savedOldList,seq,remainingList )

                x :: xs ->
                    case remainingList of
                        [] ->
                            Nothing

                        y :: ys ->
                            if x == y then
                                helper xs ys (savedSeq ++ [ x ]) (savedCurrentList ++ [ y ]) savedOldList

                            else
                                case savedCurrentList of
                                    [] ->
                                        helper (savedSeq ++ remainingSeq) ys [] [] (savedOldList ++ [ y ])

                                    y2 :: y2s ->
                                        helper (savedSeq ++ remainingSeq) (y2s ++ remainingList) [] [] (savedOldList ++ [ y ])
    in
    helper seq list [] [] []


main =
    text <| Debug.toString <| partitionBySeq [ 'a','d' ]

当然,如果您只处理字符,则还可以使用String将列表转换为String.fromList,并使用String.contains "abc" "ababcd"作为第一个版本和{{1} }来实施第二个。

,

此答案假设,如果您有Sequence 'a' 'b' 'c'并针对列表['a','a']进行测试,则希望接收结果(['a','c'],['a'])(如this comment所述)。 / p>

使用伪代码:

  1. 将列表分为两个list1list2list1的长度应与序列的长度相同。榆木为此提供了List.takeList.drop
  2. 使用辅助函数将序列转换为列表list_sequence
  3. 测试list1list_sequence是否相等
  4. 如果是,则返回元组(list1,list2)

这是实际的Elm代码: https://ellie-app.com/bjBLns4dKkra1