将列表中的连续重复模式减少为单次出现

时间:2012-11-04 21:42:07

标签: c# algorithm pattern-matching

请针对以下问题建议方法或算法参考。

要求:

  • 模式需要连续。
  • 如果在第一组减少之后可以做更多的事情,那么它们应该进一步应用
  • 请不要建议正则表达式解决方案,因为在我的情况下我必须减少一些列表
  • 结果列表必须是最短的列表
  • 对于相同的输入,它必须始终产生相同的缩减

例如:

  1. ABBABBB(BB和Bin BBB中的B匹配减少模式)=> ABAB(AB匹配减少模式)=> AB
  2. ABCDBCDA(BCD与减少模式相匹配)=> ABCDA
  3. ABC => ABC
  4. ABBA => ABA
  5. ABCBCBCBC(模式可以是BC或BCBC,选择最短的一个:BC)=> ABC
  6. ABCDBC => ABCDBC

1 个答案:

答案 0 :(得分:2)

class Program
{
    static List<T> removePatterns<T>(List<T> list)
    {
        List<T> cleaned = new List<T>();
        List<T> pattern = new List<T>();

        for (int i = 0; i < list.Count; i++)
        {
            cleaned.Add(list[i]);
            pattern.Add(list[i]);
            // check if a pattern can be found ahead, increase pattern size slowly until something can be found
            int patternSize = -1;
            for (patternSize = 1; patternSize < pattern.Count + 1; patternSize++)
            {
                List<T> currentPattern = pattern.Skip(pattern.Count - patternSize).ToList();
                Boolean matches = true;
                for (int o = 0; o < currentPattern.Count() && matches; o++)
                    matches = i + 1 + o < list.Count && list[i + 1 + o].Equals(currentPattern[o]);
                if (matches)
                {
                    pattern = new List<T>();
                    i += currentPattern.Count;
                    break;
                }
            }
        }
        if (cleaned.Count != list.Count)
            return removePatterns(cleaned);
        return cleaned;
    }

    static void test(String list, String expected)
    {
        String result = String.Join("", removePatterns<String>(list.Select(c => c.ToString()).ToList()).ToArray());
        Console.WriteLine(list + " => " + result + " = " + expected);
        Console.WriteLine(result.Equals(expected) ? "Passed" : "Failed");
    }

    static void Main(string[] args)
    {
        test("ABBABBB", "AB");
        test("ABCDBCDA", "ABCDA");
        test("ABC", "ABC");
        test("ABBA", "ABA");
        test("ABCBCBCBC", "ABC");
        test("ABCDBC", "ABCDBC");

        Console.ReadKey();
    }
}

这是我从头开始编写的。对于测试用例,它按预期工作。但它可能包含错误。