R有没有你自己编码的堆栈吗?
从字面上看,我只想从CS 102中获得一些东西。
我在下面写了代码,效果很好。但我宁愿让其他东西更具普遍性并得到证实。
语言有什么用吗?或者所有常用算法的一些包,如队列,树等等?
####################################################################################################
# Stack.R - Implments a generalized stack. Uses Reference Classes since we need mutability.
####################################################################################################
Stack <- setRefClass("Stack",
fields = list(
vStack = "vector",
nTop = "numeric"
),
methods = list(
initialize = function() {
nTop <<- 1
},
push = function(nItem) {
vStack <<- c(vStack, nItem)
nTop <<- nTop + 1
vStack[nTop-1]
},
pop = function() {
if (nTop == 1) return(NULL)
nItem <- vStack[nTop-1]
nTop <<- nTop - 1
vStack <<- vStack[1:nTop-1]
nItem
},
top = function() {
vStack[nTop-1]
}
)
)
# StackTest <- function() {
#
# say("Starting...")
# s <- Stack()
# say(s$push(1), " {push}")
# say(s$push("Hello"), " {push}")
# say(s$push(2), " {push}")
# say(s$push("World"), " {push}")
# say(s$push(3), " {push}")
# say(s$top(), " {top}")
# say(s$top(), " {top}")
# say(s$pop(), " {pop}")
# say(s$pop(), " {pop}")
# say(s$pop(), " {pop}")
# say(s$pop(), " {pop}")
# say("Finished.")
#
# }
#
# StackTest()
答案 0 :(得分:5)
并没有真正回答你的问题,但是(a)参考类似乎在改变内存管理方面做得很好,因此复制较少,但与其他基于参考的实现相比,并不一定具有高性能; (b)vStack <<- c(vStack, nItem)
范围内的“复制和追加”范式非常糟糕。这是一个小的自动收报机功能
ticker = function(s) {
i = 0
t0 = Sys.time()
while (i < 1000000) {
s$push(i)
i <- i + 1
if (i %% 10000 == 0)
print(i / as.numeric(Sys.time() - t0))
}
}
吞吐量从3,800次/秒下降到2,700次
> ticker(Stack())
[1] 3784.634
[1] 3546.138
[1] 3429.046
[1] 3303.904
[1] 3192.252
[1] 3090.162
[1] 3000.161
[1] 2908.317
[1] 2826.459
[1] 2744.961
^C
这是使用本地环境的不完整实现
s = local({
v = numeric()
list(push=function(elt) v <<- c(v, elt),
val=function() v)
})
具有更高的初始吞吐量,并且“复制和追加”策略的限制现在更加明显。
> ticker(s)
[1] 67933.63
[1] 41231.02
[1] 29095.23
[1] 22347.02
[1] 18274.56
[1] 14007.66
[1] 12436.16
[1] 11122.1
[1] 10034.59
[1] 9123.754
^C
这是一个采用与函数调用相同的本地环境方法的“预分配和填充”策略
stack <- function(type="numeric", length=1000L) {
v <- vector(type, length)
i <- 1L
list(push=function(elt) {
if (i == length(v))
length(v) <<- 1.6 * length(v)
v[[i]] <<- elt
i <<- i + 1L
}, val=function() v[seq_len(i - 1L)])
}
并且它提高了性能
> ticker(stack())
[1] 155448.8
[1] 170315.3
[1] 174391.1
[1] 177424.6
[1] 179275.5
[1] 180605.6
[1] 179693.4
[1] 180258.7
[1] 180681
[1] 181290.1
^C
我想所有这些都只是强调了你的原始观点,你想要一个没有重新发明轮子的Stack实现,也许@CarlWhitthoft隐含的一点,你可以更好地考虑利用R的算法矢量运算。
答案 1 :(得分:1)
CRAN上曾经有一个实现这些东西的“容器”包,但它似乎在几年前就已经死了:
ftp://www.r-project.org/pub/R/web/packages/Containers/index.html
你可以看看旧的来源,也许复活它并把它作为维护者?虽然这可能很有趣,因为它的大部分是一个没有明显来源的java jar文件。这解释了为什么它被拉了。可能更容易开始自己。
否则我很难找到实现。我知道我多年前也写了一个堆栈类。