如何在 Swift 中正确实现方向数组缩减挑战中的堆栈

Posted

技术标签:

【中文标题】如何在 Swift 中正确实现方向数组缩减挑战中的堆栈【英文标题】:How to properly implement stack in Direction Array Reduction challenge in Swift 【发布时间】:2020-05-20 19:30:33 【问题描述】:

我正在尝试解决 Swift 中的编码挑战。任务是构建一个接受一系列方向的函数,例如:["NORTH", "WEST", "EAST", "NORTH", "EAST", "SOUTH"]。应删除阵列中彼此相邻的任何相反方向。使用上面的示例,应该删除第二个和第三个索引(“WEST”和“EAST”)。但是,最后一个索引“SOUTH”应该保留,因为它不直接靠近数组中的“NORTH”值。

我正在尝试实现一个堆栈以比较这些值,但不能让它正常工作。这是我第一次实现堆栈,我还在习惯 Swift 语法。

我的代码是这样设置的:

struct StringStack 
    var array: [String] = []

    func peek() -> String 
        guard let topElement = array.first else  fatalError("The Stack is empty.")
        return topElement
    

    mutating func pop() -> String 
        return array.removeFirst()
    

    mutating func push(_ element: String) 
        array.insert(element, at: 0)
    


func directionsReduce(_ directions: [String]) -> [String] 
    var reducedDirs = StringStack()

    reducedDirs.push(directions[1])
    for direction in directions 
        if((direction == "NORTH" && reducedDirs.peek() == "SOUTH")
            || (direction == "SOUTH" && reducedDirs.peek() == "NORTH")
            || (direction == "EAST" && reducedDirs.peek() == "WEST")
            || (direction == "WEST" && reducedDirs.peek() == "EAST")
        ) 
            reducedDirs.pop()
         else 
            reducedDirs.push(direction)
        
    

    return reducedDirs.array


let testDirections1 = ["WEST", "WEST", "NORTH", "SOUTH", "EAST", "WEST"]
print(directionsReduce(testDirections1))

我返回的数组是["WEST", "WEST", "WEST"],但是,这应该返回["WEST", "WEST"]。我不确定如何初始化堆栈以解决此问题。我会很感激任何可以看一看的新鲜眼睛。我也很好奇这是否是实现堆栈的最佳实践,或者是否有更好的方法来应对这一挑战。感谢任何帮助或建议。

【问题讨论】:

你非常接近。使用第一个元素初始化堆栈。对于列表中的其余元素 (directions[1:]),如果堆栈为空或 peek 的结果与元素的方向不相反,则将元素添加到堆栈中。否则,弹出栈顶元素,继续下一个。 @snnguyen 这行得通,谢谢!但是,我遇到了 Swift 的另一个问题,也许您可​​能知道发生了什么。我正在运行两个单独的函数调用来检查算法(我将您的建议添加到代码中)。第一个函数调用是列出的并且运行良好。第二个函数调用直接发生在第一个函数调用的下方,具有不同的数组,但是它从 peek() 方法中抛出了 fatalError。不知道为什么会发生这种情况,因为它是完全相同的功能。也许是我忽略的结构的范围问题? 我不是 swift 专家,但查看您的代码,如果 array.first 为空(堆栈为空),peek() 会抛出 fatalError。需要添加检查栈是否为空,并进行相应处理。 【参考方案1】:

对于列表中的其余元素(directions[1:]),将元素添加到堆栈如果堆栈为空如果 peek 的结果和元素不是相反的方向。否则,弹出堆栈顶部的元素并继续下一个。

大小/长度方法对您的堆栈实现很有用。它会在peek() 之前提供检查,以防止抛出fatalError

func directionsReduce(_ directions: [String]) -> [String] 
    var reducedDirs = StringStack()

    reducedDirs.push(directions[0])
    for direction in directions[1...] 
        if ((reducedDirs.length() == 0) 
             || (!areOppositeDirections(direction, reducedDirs.peek()))
        
            reducedDirs.push(direction)
         else 
            reducedDirs.pop()
        
    

    return reducedDirs.array


let testDirections1 = ["WEST", "WEST", "NORTH", "SOUTH", "EAST", "WEST"]
print(directionsReduce(testDirections1))

【讨论】:

以上是关于如何在 Swift 中正确实现方向数组缩减挑战中的堆栈的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中正确实现不同视图控制器之间的协议和委托?

如何在 Keras 中正确实现自定义活动正则化器?

如何在媒体查询中正确切换此动画关键帧?

如何在php中正确实现结构化菜单

如何在我的 for 循环中正确实现睡眠功能? (Ubuntu)

如何在c#中正确实现等待异步[重复]