3

次の関数でスタック「クラス」を作成しました:add、、、、、、pushpopおよびsizeその他isEmptyclear

この「クラス」を R のジェネリックとして使用したいので、スクリプト内でスタックの複数のインスタンスを作成できます。どうすればこれを行うことができますか?

(スタック関数が別のスクリプトで記述されているため、クラスを引用符で囲んでいます (必ずしもクラス自体の定義とは限りません)

前もって感謝します

list <- ""
cursor = 0

#Initializes stack to empty
stack <- function(){
list <- c()
cursor = -1

assign("list",list,.GlobalEnv)
assign("cursor",cursor,.GlobalEnv)
}


#Where item is a item to be added to generic list
push <- function(item){
if(size(list) == 0){
    add(item, -1)
}else{
    add(item, 0)        
}
assign("list",list,.GlobalEnv)
}
4

2 に答える 2

5

これは、R で利用可能な正式なオブジェクト指向システムの使用を回避する @GSee 参照のスタック実装のより単純なバージョンです。単純化は、R のすべての関数がクロージャであり、関数呼び出し中に作成される関数がその呼び出し用に作成された環境。

new_stack <- function() {
    stack <- vector()
    push <- function(x) stack <<- c(stack, x)
    pop <- function() {
        tmp<-tail(stack, 1)
        stack<<-stack[-length(stack)]
        return(tmp)
    }
    structure(list(pop=pop, push=push), class='stack')
}

x <- new_stack()
x$push(1:3)
x$pop()
# [1] 3
x$pop()
# [1] 2

比較のために、S4 の実装を次に示します。

setClass('Stack', 
         representation(list='list', cursor='numeric'),  # type defs
         prototype(list=list(), cursor=NA_real_))        # default values

setGeneric('push', function(obj, ...) standardGeneric('push'))
setMethod('push', signature(obj='Stack'), 
    function(obj, x) {
        obj@list <- c(x, obj@list)
        obj
})

setGeneric('pop', function(obj, ...) standardGeneric('pop'))
setMethod('pop', signature(obj='Stack'),
    function(obj) {
        obj@cursor <- obj@list[[1]]
        obj@list <- obj@list[-1]
        obj
    }
)

x <- new('Stack')

# cursor is empty to start
x@cursor
#[1] NA

# add items
x <- push(x, 1)
x <- push(x, 2)

# pop them (move next item to cursor, remove from list)
x <- pop(x)
x@cursor
# [1] 2
x <- pop(x)
x@cursor
# [1] 1
于 2013-01-23T21:01:02.983 に答える
3

具体的には、push および pop メソッドを使用したスタック「クラス」について話しているため、ここで何が起こっているかの説明を読むことができるClosures の紹介から取得した Jeff Ryan による実装を次に示します。

new_stack <- function() { 
  stack <- new.env()
  stack$.Data <- vector()
  stack$push <- function(x) .Data <<- c(.Data,x)
  stack$pop  <- function() {
    tmp <- .Data[length(.Data)]
    .Data <<- .Data[-length(.Data)]
    return(tmp)
  }
  environment(stack$push) <- as.environment(stack)
  environment(stack$pop) <- as.environment(stack)
  class(stack) <- "stack"
  stack
}

> x <- new_stack()
> x$push(1:3)
> x$pop()
[1] 3
> x$pop()
[1] 2

次に、S3ジェネリックを作成すると...

push <- function(x, value, ...) UseMethod("push")
pop  <- function(x, ...) UseMethod("pop")
push.stack <- function(x, value, ...) x$push(value)
pop.stack  <- function(x) x$pop()

> push(x, 5)
> pop(x)
[1] 5
> pop(x)
[1] 1
于 2013-01-23T20:46:12.640 に答える