从列表中删除无关的移动

时间:2017-04-18 03:31:08

标签: c# optimization

假设您有一个从起点到终点的路线列表。什么是去除无关运动的有效方法?是否可以在不必绘制二维阵列中的整个运动的情况下?

即。如果在通过方向列表的两个位置彼此相邻时,您可以移除其间的所有移动(如果位置之间存在间隙,则无法缩短)。例如。 ...南方,东方,北方...... 可缩写为 ......东...... ...南,东,东,北...... 不能缩短。

enum Dir
    {
        North,
        South,
        East,
        West
    };

2 个答案:

答案 0 :(得分:0)

enum Dir
{
    North, South, East, West
}


static class RedundancyRemover { 

    internal static IList<Dir> RemoveRedundancy(IEnumerable<Dir> listOriginal)       {

        List<LinkedListNode<Dir>>[] nodeHistory = new List<LinkedListNode<Dir>>[4];
        for (int i = 0; i < 4; i++)
            nodeHistory[i] = new List<LinkedListNode<Dir>>();

        LinkedList<Dir> list = new LinkedList<Dir>(listOriginal);
        LinkedListNode<Dir> curNode = list.First;

        while (curNode != null)   {
            var curDirInd = (int) curNode.Value;
            var nextNode = curNode.Next;

            var oppHistory = nodeHistory[curDirInd^1];
            int oppHistCount = oppHistory.Count;

            if (oppHistCount > 0)    {
                // Has pair - remove this node with its pair
                list.Remove(curNode);
                list.Remove(oppHistory[--oppHistCount]);
                oppHistory.RemoveAt(oppHistCount);
            }
            else
                nodeHistory[curDirInd].Add(curNode);

            curNode = nextNode;
        }

        return list.ToArray();

    }



}

答案 1 :(得分:0)

更简单的方法:只计算每个方向:

enum Dir
{
    North, South, East, West
}

static class RedundancyRemover
{

    static IList<Dir> RemoveRedundancy(IList<Dir> list)    {
        int[] occurenceCount = new int[4];

        foreach (var dir in list) occurenceCount[(int)dir]++;

        var newList = new List<Dir>();

        for (int i=0; i<4; i+=2)  {
            int v1 = occurenceCount[i];
            int v2 = occurenceCount[i+1];
            if (v1 > v2)
                repeat(newList, (Dir)i, v1 - v2);
            else
            if (v1 < v2)
                repeat(newList, (Dir)(i + 1), v2 - v1);

        }

        return newList;

    }

    private static void repeat(IList<Dir> list, Dir dir, int count)   {
        while (--count >= 0)  list.Add(dir);
    }

}