【问题标题】:Check if N sections intersect检查N部分是否相交
【发布时间】:2020-10-08 07:47:31
【问题描述】:

伙计们!我需要实现功能 static bool CheckSectionsIntersect 检查部分是否相交(右→;左←;下↓; 向上↑)。以连续方向的形式给定 N 个连续的具有固定尺寸的垂直和水平部分的列表。我不得不认为我会有N个部分的路线。 如果我到了以前去过的地方,该函数应该返回 True 。 例如:

N = 6: { 上、左、下、下、右、上} - 返回 True。

⬇⬅
⬇⬆  <- Start
➡⬆

N = 4: {下、左、上、左} - 返回 False。

⬅⬇  <- Start
⬆⬅

我写的代码不完整,因为我需要一些关于函数应该如何的建议:

    static void Main()
    {
        string userInput = Console.ReadLine();
        int numberOfSections = Convert.ToInt32(userInput);
        string[] sectionDirection = new string[numberOfSections];
        for (int i = 0; i < numberOfSections; i++)
        {
            sectionDirections[i] = Console.ReadLine();
        }

        Console.WriteLine(CheckSectionsIntersect(sectionDirection, numberOfSections));
    }

    static bool CheckSectionsIntersect(string[] sectionDirection, int numberOfSections)
    {
        return true; // I need an implementation here
    }
}

}

请问我对这个实现有什么建议吗? 非常感谢!

【问题讨论】:

  • 对不起,我不明白你的问题。你能改写一下吗?谢谢!

标签: c# function intersection directions


【解决方案1】:

如果您想到一个笛卡尔网格,并且从 0,0 开始,x 坐标向左/向右递增/递减,y 坐标向上/向下,那么答案是您是否回到 0,0在任何时候。

static Dictionary<string,(int X,int Y)> transforms = new Dictionary<string, (int X, int Y)>{
    ["U"] = (0,1),
    ["D"] = (0,-1),
    ["L"] = (-1,0),
    ["R"] = (1,0)
};

static bool CheckSectionsIntersect(string[] sectionDirection, int numberOfSections)
{
    (int X, int Y) pos = (0,0);
    for(var i = 0;i<numberOfSections;i++)
    {
        if(!transforms.TryGetValue(sectionDirection[i], out var transform))
           throw new ArgumentException("sectionDirections");
        pos.X += transform.X;
        pos.Y += transform.Y;
        if(pos.X == 0 && pos.Y == 0)
            return true;                
    }
    return false;
}

您的 2 个测试用例的实时示例:https://dotnetfiddle.net/p5JY61

上面只检查你最终回到 0,0 - 但是如果你想确定你是否输入了你以前去过的任何坐标,你只需要跟踪你一直在使用集合的位置而不是检查你是否回到了 0,0,而是检查你是否在你以前去过的任何地方。

static bool CheckSectionsIntersect(string[] sectionDirection, int numberOfSections)
{
    (int X, int Y) pos = (0,0);
    var visited = new List<(int X, int Y)>{ pos };
    for(var i = 0;i<numberOfSections;i++)
    {
        if(!transforms.TryGetValue(sectionDirection[i], out var transform))
           throw new ArgumentException("sectionDirections");
        (int X, int Y) newPos = (pos.X + transform.X, pos.Y + transform.Y);
        
        if(visited.Contains(newPos))
            return true;    
                    
        pos = newPos;
        visited.Add(newPos);
    }
    return false;
}

现场示例:https://dotnetfiddle.net/FyJYrr

【讨论】:

  • 对于非起点部分。在哈希集中添加坐标,如果新值已经在其中,则返回 true;
  • 只涵盖起点的交点。我可以在任何点dotnetfiddle.net/wkEs3l 上编辑您的答案吗?仅添加 var existing = new HashSet&lt;(int,int)&gt;{pos};if( !existing.Add(pos)) return true; 。因为它是 100% 的代码,只需一行新代码。
  • @DragandDrop 我没有问题原则上你编辑我的答案。你甚至不需要我的许可——这就是 SE 的工作方式!但我可能会争辩说,我们不知道这是否是实际要求,因此可能过于复杂。作为 另一个 答案(或此答案中的第二个代码块),我认为这很好,如果您愿意,欢迎您从我的代码中获取灵感。
  • @SimonaM。您能否确认此答案是否完整 - 您是否试图确定您是在开始时结束,还是在您以前去过的任何地方结束?您的 true 示例/测试用例在开始时结束。
  • @Jamiec,我需要确定我是否在我去过的地方结束。我是一个初学者,我还没有在我的课程中学习字典以及如何引发异常。我正在尝试使用数组找到另一种解决方案。欢迎提出任何建议。
【解决方案2】:

我不确定我是否明白你在说什么。 如果你想看看你是否在你去过的地方结束,只需制作一个元组数组。在每次移动中保存您的坐标(从 0,0 开始)。在路径的末尾检查您的坐标是否在数组中。或者在每次移动结束时,如果您想检查您已经去过的地方。

编辑:

static bool CheckSectionsIntersect(string[] sectionDirection, int numberOfSections)
    {
        (int X, int Y) pos = (0, 0); //Variable to track our actual position. Start position (0,0)
        List<(int X, int Y)> coordinates = new List<(int X, int Y)>(); //List where we are going to keep the coordinates
        foreach (string move in sectionDirection) //for each move
        {
            coordinates.Add(pos); //Add our current position to the list
            switch (move)         //Make a move
            {
                case "left":
                    pos.X -= 1;
                    break;
                case "right":
                    pos.X += 1;
                    break;
                case "down":
                    pos.Y -= 1;
                    break;
                case "up":
                    pos.Y += 1;
                    break;
            }
            if (coordinates.Contains(pos)) { return true; } //If our new position is already in the list, we have been there.
        }
        return false;
    }

我已经对其进行了测试,并且可以正常工作。 为此,使用列表比使用数组更容易。这是由于方法 .Add() 和 .contains()。

此代码不是最强的(例如它不接受大写字母)。但既然你是初学者,应该就够了。我鼓励您改进它以继续学习。

【讨论】:

  • Raulmd,你没看错,我想看看我是否在我去过的地方结束。
  • 我尝试按照您的建议编写代码,但没有成功。我不明白如何写动作。你能帮我吗?谢谢!
  • 没问题,我已经用一个例子编辑了答案
  • 如果您只想检查端点。将“如果”从 foreach 中删除。
  • 如果您的问题得到了很好的回答,请选择答案之一作为解决方案。这样帖子就会(解决)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-15
  • 1970-01-01
  • 2011-10-27
  • 2017-12-09
  • 2013-06-16
  • 2019-03-15
相关资源
最近更新 更多