我是Swift和iOS编程的新手。
我正在尝试测试一个简单的算法并需要一个Stack数组。不必任何花哨的东西(堆栈的Ints会做)。
我从The Swift Programming Language documentation得到了堆栈实现:
struct IntStack {
var items = [Int]()
mutating func push(item: Int) {
items.append(item)
}
mutating func pop() -> Int {
return items.removeLast()
}
mutating func count() -> Int {
return items.count
}
mutating func show() {
println(items)
}
}
计数和显示功能是我的贡献。但是当我尝试声明一个Stacks数组时,我得到一个错误......
var lines = IntStack()[5]
“IntStack”没有名为subscript的成员
我猜它与Optionals有关,但可以弄清楚它是什么......
任何帮助?
答案 0 :(得分:8)
可堆叠协议
protocol Stackable {
associatedtype Element
func peek() -> Element?
mutating func push(_ element: Element)
@discardableResult mutating func pop() -> Element?
}
extension Stackable {
var isEmpty: Bool { peek() == nil }
}
堆栈
struct Stack<Element>: Stackable where Element: Equatable {
private var storage = [Element]()
func peek() -> Element? { storage.first }
mutating func push(_ element: Element) { storage.append(element) }
mutating func pop() -> Element? { storage.popLast() }
}
extension Stack: Equatable {
static func == (lhs: Stack<Element>, rhs: Stack<Element>) -> Bool { lhs.storage == rhs.storage }
}
extension Stack: CustomStringConvertible {
var description: String { "\(storage)" }
}
extension Stack: ExpressibleByArrayLiteral {
init(arrayLiteral elements: Self.Element...) { storage = elements }
}
var stack = Stack<Int>()
stack.push(1)
stack.push(2)
stack.push(3)
print(stack.peek())
print(stack.pop())
print(stack)
print(stack == Stack<Int>())
stack = [3,2,1]
print(stack)
答案 1 :(得分:3)
您在那里做的事情没有问题 - 这不是声明数组的语法。如果你想要一个包含5个堆栈的数组,你可以这样做:
[IntStack(), IntStack(), IntStack(), IntStack(), IntStack()]
或者,您可以像这样初始化数组:
Array(count: 5, repeatedValue: IntStack())
此外,您不需要将您的功能标记为mutating
,除非它们实际上改变了结构 - 因此count()
和show()
不需要它。< / p>
答案 2 :(得分:2)
可以使用特定于堆栈的方法来扩展数组。这可能是您想要的,也可能不是您想要的,这取决于您是否想禁止像访问这样的数组。
protocol Stack {
associatedtype Element
mutating func push(item: Element)
// allows discarding the result without generating a warning.
@discardableResult
mutating func pop() -> Element?
func peek() -> Element?
var count: Int { get }
}
extension Array: Stack {
mutating func push(item: Element) {
self.append(item)
}
mutating func pop() -> Element? {
if let last = self.last {
self.remove(at: self.count - 1)
return last
}
return .none
}
func peek() -> Element? {
self.last
}
}
简单的测试用例:
class StackTests: XCTestCase {
func testExample() throws {
var stack = Array<Int>()
XCTAssertEqual(stack.peek(), .none, "stack is empty, peek returns none")
XCTAssertEqual(stack.pop(), .none, "stack is empty, pop returns none")
stack.push(item: 0)
stack.push(item: 1)
stack.push(item: 2)
XCTAssertEqual(stack.peek(), 2)
XCTAssertEqual(stack.pop(), 2)
XCTAssertEqual(stack.peek(), 1)
XCTAssertEqual(stack.pop(), 1)
XCTAssertEqual(stack.peek(), 0)
XCTAssertEqual(stack.pop(), 0)
}
}
答案 3 :(得分:1)
初始化时无需声明堆栈的大小。 Jus称这个就足够了。
var lines = IntStack()
另请注意,count()和show()方法不应该是变异的,因为它们不会以任何方式修改结构。
答案 4 :(得分:0)
这是使用Swift泛型的Stack实现,
struct Fruit {
let fruitName : String
let color : String
init(_ name: String,_ color: String) {
self.fruitName = name
self.color = color
}
}
let fruit1 = Fruit("Apple", "Red")
let fruit2 = Fruit("Grapes", "Green")
let fruitStack = Stack<Fruit>()
fruitStack.push(fruit1)
fruitStack.push(fruit2)
let fruitFfromStack = fruitStack.pop()
print("Fruit popped from Stack, Name : \(String(describing: fruitFfromStack?.fruitName)) ,Color : \(String(describing: fruitFfromStack?.color))")
let fruitFfromStack1 = fruitStack.pop()
print("Fruit popped from Stack, Name : \(String(describing: fruitFfromStack1?.fruitName)) ,Color : \(String(describing: fruitFfromStack1?.color))")
完整代码在这里:
https://reactcodes.blogspot.com/2019/01/generic-stack-implementation-with.html
答案 5 :(得分:0)
只需查看此代码。带有通用数据类型且不使用数组的堆栈示例。
class Node<T>: CustomStringConvertible {
let value: T
var next: Node?
var description: String {
guard let next = next else { return "\(value)" }
return "\(value)\n" + String(describing: next)
}
init(value: T) {
self.value = value
}
}
// Stack class to hold all items
class Stack<T>: CustomStringConvertible {
var top: Node<T>?
var description: String {
guard let top = top else { return "---- Stack is EMPTY ----" }
return "---- Stack Begin ----\n" + String(describing: top) + "\n---- Stack End ----"
}
// push
func push(_ value: T) {
let currentTop = top
top = Node(value: value)
top?.next = currentTop
}
@discardableResult
func pop() -> T? {
let currentTop = top
top = top?.next
return currentTop?.value
}
@discardableResult
func peek() -> T? {
return top?.value
}
}
答案 6 :(得分:0)
出色的实施!一个想法:我认为应该是:
{{.PageTitle}}