You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell中过滤列表内循环排列元素的技术实现问询

Filtering Out Elements That Are Cyclic Permutations of Others in a List

Alright, let's break down how to solve this problem. The goal is to take a list of strings and keep only those elements that don't have any other element in the list which is a cyclic permutation of them.

First, let's recap the cyclic permutation check you mentioned—super useful, but important to remember it only works for strings of the same length. That's our first clue: we can group the list by string length right off the bat, since different-length strings can never be cyclic permutations of each other.

Step-by-Step Approach

Here's a straightforward plan to get the job done:

  • Group by length: Split the original list into sublists where every string in a sublist has the same length. This avoids wasting time checking cyclic permutations between strings that can't possibly qualify.
  • Create a "standard form" for each string: For any set of cyclic permutations, pick a single representative (like the lexicographically smallest one). For example, both "abc" and "cab" would have the standard form "abc". This lets us easily group cyclic permutations together.
  • Count standard form occurrences: For each length group, count how many times each standard form appears. If a standard form shows up more than once, that means there are multiple cyclic permutations in the group.
  • Filter the list: Keep only those strings whose standard form occurs exactly once in their length group—these are the elements with no cyclic duplicates in the original list.

Example Implementation (Haskell)

Since your cyclic check uses Haskell syntax, let's stick with that for the code example. We'll use Data.Map for counting and some list utilities:

import Data.List (groupBy, sortBy)
import Data.Function (on)
import qualified Data.Map as Map

-- Generate the lexicographically smallest cyclic permutation (standard form)
standardForm :: String -> String
standardForm s = minimum [drop i (s ++ s) | i <- [0 .. length s - 1]]

-- Filter out elements that have any cyclic permutation in the list
filterNonCyclicDuplicates :: [String] -> [String]
filterNonCyclicDuplicates strs = 
  let
    -- Group strings by their length (sorted to keep groups together)
    lengthGroups = groupBy ((==) `on` length) $ sortBy (compare `on` length) strs
    
    -- Process each length group to keep only non-duplicate cyclic elements
    processGroup :: [String] -> [String]
    processGroup group =
      let
        -- Get standard form for every string in the group
        forms = map standardForm group
        -- Count how many times each standard form appears
        formCounts = foldr (\form -> Map.insertWith (+) form 1) Map.empty forms
      in
        -- Keep strings where their standard form occurs exactly once
        [str | (str, form) <- zip group forms, Map.lookup form formCounts == Just 1]
  in
    -- Combine results from all length groups
    concatMap processGroup lengthGroups

How It Works

Let's test this with a sample input:

sampleList = ["abc", "cab", "def", "fed", "xyz"]
filterNonCyclicDuplicates sampleList  -- Output: ["xyz"]
  • "abc" and "cab" share the standard form "abc" (count = 2), so both get filtered out.
  • "def" and "fed" share the standard form "def" (count = 2), so both get filtered out.
  • "xyz" has a unique standard form (count = 1), so it's kept.

Notes

  • If your list has duplicate strings (e.g., ["abc", "abc"]), they'll be filtered out too—since identical strings are trivially cyclic permutations of each other.
  • The standardForm function uses a simple approach: it creates s ++ s (which contains every cyclic permutation as a substring) and picks the smallest substring of the original length. For very long strings, you could optimize this to avoid generating all substrings, but this works great for most use cases.

内容的提问来源于stack exchange,提问作者Mathis Panzani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:34:02