【问题标题】:How to make sequences that may be empty?如何制作可能为空的序列?
【发布时间】:2021-01-09 21:18:38
【问题描述】:

我最近尝试将 some pseudocode 改编为就地快速排序,引用如下:

function quicksort(array)
    if length(array) > 1
        pivot := select any element of array
        left := first index of array
        right := last index of array
        while left ≤ right
            while array[left] < pivot
                left := left + 1
            while array[right] > pivot
                right := right - 1
            if left ≤ right
                swap array[left] with array[right]
                left := left + 1
                right := right - 1
        quicksort(array from first index to right)
        quicksort(array from left to last index)

按照这个,我写了这段代码:

quicksort<-function(array)
{
  len<-length(array)
  if(len>1)
  {
    left<-1
    right<-len
    pivot<-array[(left+right)%/%2]
    while(left<=right)
    {
      while(array[left]<pivot){left<-left+1}
      while(array[right]<pivot){right<-right-1}
      if(left<=right)
      {
        array[c(left,right)]<-array[c(right,left)]
        left<-left+1
        right<-right-1
      }
    }
    array<-quicksort(array[1:right])#Bug here
    array<-quicksort(array[left:len])
  }
  array
}

如果您使用多个整数作为输入运行此代码,您会发现它最终会尝试对 NA 列表进行排序。我怀疑问题在于,当right 为零时,pseduocode 希望 array from first index to right - 我的 1:right - 被读取为空序列。众所周知,R 实际上会将1:0 读作序列0 1

是否有任何功能可以获得我想要的行为?我可以用 if 语句来做到这一点,但 R 通常对序列足够好,我不禁认为会有更好的方法。我尝试使用seq,但如果您尝试使用seq(from=1,to=0,by=1) 之类的任何内容,则会引发错误。

【问题讨论】:

    标签: r list sorting sequence quicksort


    【解决方案1】:

    代码有两个问题:

    1. 其中一个不等号被翻转。
    2. 需要修改数组分配以仅更改元素的子集,而不是替换(和缩小)整个数组。

    这是修改后的代码

    quicksort <- function(array) {
      len <- length(array)
      if(len > 1) {
        left <- 1
        right <- len
        pivot <- array[(left+right)%/%2]
        while(left <= right)
        {
          while(array[left] < pivot){ 
            left <- left + 1
          }
          while(array[right] > pivot) { # Changed "<" to ">"
            right <- right - 1
          }
          if(left <= right) {
            array[c(left, right)] <- array[c(right, left)]
            left <- left + 1
            right <- right - 1
          }
        }
        
        # Modified the following two lines to only set a subset of array
        array[1:right] <- quicksort(array[1:right])
        array[left:len] <- quicksort(array[left:len])
      }
      array
    }
    
    
    quicksort(c(2, 6, 3, 1, 4, 5))
    #> [1] 1 2 3 4 5 6
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多