简体   繁体   English

在r中插入排序,错误为“缺少需要TRUE / FALSE的值”

[英]Insertion sort in r with error “missing value where TRUE/FALSE needed”

I want to build insertion sort algorithm in r: 我想在r中建立插入排序算法:

  1. Given a vector x, let the initial unsorted vector u be equal to x, 给定向量x,让初始未排序向量u等于x,
    and the initial sorted vector s be a vector of length 0. 排序后的初始向量s为长度为0的向量。
  2. Remove first element of u and insert it into s so that s is still sorted. 删除u的第一个元素并将其插入s中,以便s仍然排序。
  3. If u is not empty then go back to step 2. 如果u不为空,则返回步骤2。

Here is my code: 这是我的代码:

x <- round(runif(1000,1,100)
u <- x
s <- vector(mode="numeric", length=0


    for(i in 1:length(u)){
        number <-u[i]
        u <- u[-i]
        for(j in 1:length(s)){
            if(length(s) == 0){
                s <- c(s,number)
                break
            }else{
                if(s[j]>=number){
                    s <- append(s,number,j-1)
                    break
                }
            }
            if(s[length(s)]<number){
                s <- c(s,number)
            }
        }
    }

First of all, when length of u = 500 it throws me an error: 首先,当u的长度= 500时,会抛出一个错误:

Error in if (s[j] >= number) { : missing value where TRUE/FALSE needed

next, it sorted incorrectly(for example it could be more ones than in original vector u, or for example less twos then in original vector u) 接下来,它排序不正确(例如,可能比原始向量u中的位数多,或者比原始向量u中的位数少二)

So I have two questions: 所以我有两个问题:

1)How can we fix that in THIS code? 1)如何在此代码中解决该问题?

2)Can you suggest another code, which is more efficient than my? 2)您能建议另一个比我更有效的代码吗?

PS Of course the code should be without sort and order command. PS当然,代码应该没有排序和排序命令。 Many thanks 非常感谢

Your first question is an easy fix: when you extract a number out of your vector u, what you are really doing, is just drawing a random number from the sample without replacement. 您的第一个问题是一个简单的解决方法:当您从向量u中提取一个数字时,您实际上所做的就是从样本中抽取一个随机数而不进行替换。 So just always take the first value. 因此,始终取第一值。

# Change the current to this:
number <-u[1]
u <- u[-1]

For your second question: what a fun exercise! 对于您的第二个问题:多么有趣的运动! My go at it was to just implement the selection sort pseudo-code from Wikipedia , (which you could just do) but with blindfolds: I cannot look into "the bag" of x but only see my just-drawn item - this I found to be more like what you are asking for. 我的目的是仅仅实现来自Wikipedia选择排序伪代码 (您可以这样做),但是蒙住眼睛:我无法查看x “袋子”,而只能看到我刚刚绘制的项目-我发现了这一点更符合您的要求。

How do I go about solving this? 我该如何解决呢? Simple: I draw a value from x . 简单:我从x绘制一个值。 Call it my control variable. 称之为我的control变量。 Then for every draw I put the new value into a pile of small if less than (or equal) to control. 然后,对于每次平局,我都会将新值放到一堆small如果小于(或等于))中进行控制。 Otherwise I put it into the large pile. 否则,我把它放到large一堆。 When I have distributed all values, I do this algorithm again for each pile. 分配所有值后,我将对每个堆再次执行此算法。 I continue until my piles are all of size 1. The implementation of this below. 我继续进行直到所有的堆都达到大小1。下面的实现。

mysort <- function(x){
    if(length(x) <= 1){
        return(x)       ## If nothing to sort, return itself
    }

    control <- x[1]
    small <- c()
    big <- c()

    for(test in x[-1]){
        if(test <= control){
            small <- c(small,test)  ## Less than control in small
        }
        if(test > control){
            big <- c(big,test)      ## Bigger than control in big
        }
    }

    ## Sort the new piles with the same procedure recursively.
    small <- mysort(small)          
    big <- mysort(big)

    ## Return the improved order
    c(small,control,big)
}

mysort(c(2,1,1,2,2,2,3,3,-3,-Inf,Inf,0,pi))
# [1]      -Inf -3.000000  0.000000  1.000000  1.000000  2.000000  2.000000  2.000000
# [9]  2.000000  3.000000  3.000000  3.141593       Inf

We can compare speeds with the microbenchmark package, if we wrap your implementation (without the superfluous while -loop) in a function yoursort . 如果将您的实现(没有多余的while yoursort )包装在函数yoursort ,那么我们可以将速度与microbenchmark包进行比较。

library(microbenchmark)
a <- rnorm(1e3)
microbenchmark(b <- mysort(a),times = 10)
# Unit: milliseconds
#           expr      min      lq     mean   median       uq      max neval
# b <- mysort(a) 37.76747 39.2302 41.96171 40.99288 43.07412 47.85377    10

microbenchmark(c <- yoursort(a),times = 10)
# Unit: milliseconds
#             expr      min       lq     mean   median       uq      max neval
# c <- yoursort(a) 786.4544 808.2312 861.8072 840.7868 879.4946 1059.913    10
microbenchmark(sort(a),times = 10)
# Unit: microseconds
#    expr     min      lq     mean   median      uq     max neval
# sort(a) 192.763 194.384 242.7633 201.1335 263.497 390.386    10

Neither are any match to the already implemented sort function. 与已实现的sort功能都不匹配。

And of course, do they actually do the correct sorting? 当然,他们实际上进行了正确的排序吗?

any(b != sort(a)) ## Are there any elements that do not match?
# [1] FALSE
any(c != sort(a))
# [1] FALSE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM