减少字符串数组中序列的最佳方法

时间:2020-03-05 18:51:38  来源:igfitidea点击:

拜托,既然我已经重新编写了这个问题,并且在急于想进一步编辑快速回答或者过早地关闭它之前,让我指出,这不是该问题的重复。我知道如何从数组中删除重复项。

这个问题是关于从数组中删除序列,严格意义上讲不是重复。

考虑数组中元素的此顺序;

[0] a
[1] a
[2] b
[3] c
[4] c
[5] a
[6] c
[7] d
[8] c
[9] d

在此示例中,我想获得以下内容...

[0] a
[1] b
[2] c
[3] a
[4] c
[5] d

请注意,保留了重复的元素,但是将同一元素的序列简化为该元素的单个实例。

此外,请注意,当两行重复时,它们应减少为一组(两行)。

[0] c
[1] d
[2] c
[3] d

...减少到...

[0] c
[1] d

我在Cbut算法中以任何语言编写的代码都值得赞赏。

解决方案

回答

我会将它们全部转储到我们最喜欢的Set实现中。

编辑:现在,我明白了这个问题,原始解决方案看起来像是执行此操作的最佳方法。只需循环遍历一次数组,保留一个标志数组以标记要保留的元素,再加上一个计数器以跟踪新数组的大小。然后再次循环以将所有Keeper复制到新阵列。

回答

我同意,如果我们可以将字符串转储到Set中,那么这可能是最简单的解决方案。

如果由于某种原因我们没有访问Set实现的权限,我只需要按字母顺序对字符串进行排序,然后遍历一次并删除重复项即可。如何对它们进行排序并从列表中删除重复项将取决于我们运行代码的语言和环境。

编辑:哦,舔...。根据澄清,我看到我们希望即使在单独的行上也可能出现模式。我的方法无法解决问题。对不起。这是问题。如果我有以下文件。

一种

一种

b

C

C

一种

一种

b

C

C

我们希望它简化为

一种

b

C

回答

编辑:进行了一些更改和新的建议

那推拉窗呢...

REMOVE LENGTH 2: (no other length has other matches)
//the lower case letters are the matches
ABCBAbabaBBCbcbcbVbvBCbcbcAB  
__ABCBABABABBCBCBCBVBVBCBCBCAB

REMOVE LENGTH 1 (duplicate characters):
//* denote that a string was removed to prevent continual contraction
//of the string, unless this is what you want.
ABCBA*BbC*V*BC*AB
_ABCBA*BBC*V*BC*AB

RESULT:
ABCBA*B*C*V*BC*AB == ABCBABCVBCAB

这当然是从length = 2开始,将其增加到L / 2并向下迭代。

我也在考虑另外两种方法:

  • 有向图-使用数据设置有状态有向图,并使用字符串对其进行迭代,如果找到一个循环,则将有一个重复项。我不确定对这些周期进行检查是多么容易...可能是一些动态编程,因此它可能等同于下面的方法2. 我将不得不考虑更长的时间。
  • 距离矩阵-使用levenstein距离矩阵,我们可能能够检测到对角线移动(偏离对角线)的重复项,成本为0。这可能表示数据重复。我将不得不考虑更多。

回答

这是我写的解决这个问题的Capp。

需要
aabccacdcd

输出
abcacd

可能看起来很凌乱,花了我一些时间让我的头绕着动态图案长度。

class Program
{
    private static List<string> values;
    private const int MAX_PATTERN_LENGTH = 4;

    static void Main(string[] args)
    {
        values = new List<string>();
        values.AddRange(new string[] { "a", "b", "c", "c", "a", "c", "d", "c", "d" });

        for (int i = MAX_PATTERN_LENGTH; i > 0; i--)
        {
            RemoveDuplicatesOfLength(i);
        }

        foreach (string s in values)
        {
            Console.WriteLine(s);
        }
    }

    private static void RemoveDuplicatesOfLength(int dupeLength)
    {
        for (int i = 0; i < values.Count; i++)
        {
            if (i + dupeLength > values.Count)
                break;

            if (i + dupeLength + dupeLength > values.Count)
                break;

            var patternA = values.GetRange(i, dupeLength);
            var patternB = values.GetRange(i + dupeLength, dupeLength);

            bool isPattern = ComparePatterns(patternA, patternB);

            if (isPattern)
            {
                values.RemoveRange(i, dupeLength);
            }
        }
    }

    private static bool ComparePatterns(List<string> pattern, List<string> candidate)
    {
        for (int i = 0; i < pattern.Count; i++)
        {
            if (pattern[i] != candidate[i])
                return false;
        }

        return true;
    }
}

固定初始值以匹配问题值