Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 按Ruby数组复杂度顺序插入方法_Arrays_Ruby_Complexity Theory - Fatal编程技术网

Arrays 按Ruby数组复杂度顺序插入方法

Arrays 按Ruby数组复杂度顺序插入方法,arrays,ruby,complexity-theory,Arrays,Ruby,Complexity Theory,在Ruby中,当n是数组大小时,插入数组的预期数量级是多少? 感谢复杂性为O(N),因为此方法使用了Memmove()在rb_ary_splice()方法下,该方法本身就是O(N),请查看源代码: rb_ary_insert(int argc, VALUE *argv, VALUE ary) { long pos; rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS); rb_ary_modify_check(ary); if

在Ruby中,当n是数组大小时,插入数组的预期数量级是多少?
感谢

复杂性为O(N),因为此方法使用了
Memmove()
rb_ary_splice()
方法下,该方法本身就是O(N),请查看源代码:

rb_ary_insert(int argc, VALUE *argv, VALUE ary)
{
    long pos;

    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
    rb_ary_modify_check(ary);
    if (argc == 1) return ary;
    pos = NUM2LONG(argv[0]);
    if (pos == -1) {
    pos = RARRAY_LEN(ary);
    }
    if (pos < 0) {
    pos++;
    }
    rb_ary_splice(ary, pos, 0, rb_ary_new4(argc - 1, argv + 1));
    return ary;
}

rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl)
{
    long rlen;
    long olen;

    if (len < 0) rb_raise(rb_eIndexError, "negative length (%ld)", len);
    olen = RARRAY_LEN(ary);
    if (beg < 0) {
    beg += olen;
    if (beg < 0) {
        rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
             beg - olen, -olen);
    }
    }
    if (olen < len || olen < beg + len) {
    len = olen - beg;
    }

    if (rpl == Qundef) {
    rlen = 0;
    }
    else {
    rpl = rb_ary_to_ary(rpl);
    rlen = RARRAY_LEN(rpl);
    olen = RARRAY_LEN(ary); /* ary may be resized in rpl.to_ary too */
    }
    if (beg >= olen) {
    VALUE target_ary;
    if (beg > ARY_MAX_SIZE - rlen) {
        rb_raise(rb_eIndexError, "index %ld too big", beg);
    }
    target_ary = ary_ensure_room_for_push(ary, rlen-len); /* len is 0 or negative */
    len = beg + rlen;
    ary_mem_clear(ary, olen, beg - olen);
    if (rlen > 0) {
        ary_memcpy0(ary, beg, rlen, RARRAY_CONST_PTR(rpl), target_ary);
    }
    ARY_SET_LEN(ary, len);
    }
    else {
    long alen;

    if (olen - len > ARY_MAX_SIZE - rlen) {
        rb_raise(rb_eIndexError, "index %ld too big", olen + rlen - len);
    }
    rb_ary_modify(ary);
    alen = olen + rlen - len;
    if (alen >= ARY_CAPA(ary)) {
        ary_double_capa(ary, alen);
    }

    if (len != rlen) {
        RARRAY_PTR_USE(ary, ptr,
               MEMMOVE(ptr + beg + rlen, ptr + beg + len,
                   VALUE, olen - (beg + len)));
        ARY_SET_LEN(ary, alen);
    }
    if (rlen > 0) {
        MEMMOVE(RARRAY_PTR(ary) + beg, RARRAY_CONST_PTR(rpl), VALUE, rlen);
    }
    }
    RB_GC_GUARD(rpl);
}
rb_ary_插入(int-argc,VALUE*argv,VALUE-ary)
{
长pos;
rb_校验(argc,1,无限参数);
rb\U ary\U修改检查(ary);
如果(argc==1)返回ary;
pos=NUM2LONG(argv[0]);
如果(位置==-1){
pos=RARRAY_LEN(ary);
}
如果(位置<0){
pos++;
}
rb_ary_拼接(ary,pos,0,rb_ary_new4(argc-1,argv+1));
回归分析;
}
rb_ary_拼接(值ary、长beg、长len、值rpl)
{
龙乐伦;
长橄榄油;
如果(len<0)rb_升高(rb_eIndexError,“负长度(%ld)”,len);
olen=RARRAY_LEN(ary);
if(beg<0){
beg+=olen;
if(beg<0){
rb_raise(rb_eIndexError,“索引%ld对于数组太小;最小值:%ld”,
beg-olen,-olen);
}
}
if(olen=olen){
价值目标;
如果(beg>ARY_最大尺寸-rlen){
rb_升高(rb_eIndexError,“索引%ld太大”,beg);
}
target_ari=ari_确保_push(ari,rlen len)的空间;/*len为0或负*/
len=beg+rlen;
ary_mem_clear(ary、olen、beg-olen);
如果(rlen>0){
ary_memcpy0(ary、beg、rlen、RARRAY_CONST_PTR(rpl)、target_ary);
}
ARY_SET_LEN(ARY,LEN);
}
否则{
龙阿伦;
如果(olen-len>ARY_MAX_SIZE-rlen){
rb_raise(rb_EINDEXERR,“索引%ld太大”,olen+rlen-len);
}
rb_ary_modify(ary);
alen=olen+rlen-len;
如果(alen>=ARY_CAPA(ARY)){
ary_double_capa(ary,alen);
}
如果(len!=rlen){
RARRAY_PTR_使用(ary,PTR,
MEMMOVE(ptr+beg+rlen,ptr+beg+len,
值,olen-(beg+len));
ARY_SET_LEN(ARY,alen);
}
如果(rlen>0){
MEMMOVE(RARRAY_PTR(ari)+beg、RARRAY_CONST_PTR(rpl)、VALUE、rlen);
}
}
RB_GC_防护装置(rpl);
}
以下是MEMMOVE函数的参考:

复杂度为O(N),因为此方法使用
Memmove()
rb\u ary\u splice()
方法(其本身为O(N))下,请查看源代码:

rb_ary_insert(int argc, VALUE *argv, VALUE ary)
{
    long pos;

    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
    rb_ary_modify_check(ary);
    if (argc == 1) return ary;
    pos = NUM2LONG(argv[0]);
    if (pos == -1) {
    pos = RARRAY_LEN(ary);
    }
    if (pos < 0) {
    pos++;
    }
    rb_ary_splice(ary, pos, 0, rb_ary_new4(argc - 1, argv + 1));
    return ary;
}

rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl)
{
    long rlen;
    long olen;

    if (len < 0) rb_raise(rb_eIndexError, "negative length (%ld)", len);
    olen = RARRAY_LEN(ary);
    if (beg < 0) {
    beg += olen;
    if (beg < 0) {
        rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
             beg - olen, -olen);
    }
    }
    if (olen < len || olen < beg + len) {
    len = olen - beg;
    }

    if (rpl == Qundef) {
    rlen = 0;
    }
    else {
    rpl = rb_ary_to_ary(rpl);
    rlen = RARRAY_LEN(rpl);
    olen = RARRAY_LEN(ary); /* ary may be resized in rpl.to_ary too */
    }
    if (beg >= olen) {
    VALUE target_ary;
    if (beg > ARY_MAX_SIZE - rlen) {
        rb_raise(rb_eIndexError, "index %ld too big", beg);
    }
    target_ary = ary_ensure_room_for_push(ary, rlen-len); /* len is 0 or negative */
    len = beg + rlen;
    ary_mem_clear(ary, olen, beg - olen);
    if (rlen > 0) {
        ary_memcpy0(ary, beg, rlen, RARRAY_CONST_PTR(rpl), target_ary);
    }
    ARY_SET_LEN(ary, len);
    }
    else {
    long alen;

    if (olen - len > ARY_MAX_SIZE - rlen) {
        rb_raise(rb_eIndexError, "index %ld too big", olen + rlen - len);
    }
    rb_ary_modify(ary);
    alen = olen + rlen - len;
    if (alen >= ARY_CAPA(ary)) {
        ary_double_capa(ary, alen);
    }

    if (len != rlen) {
        RARRAY_PTR_USE(ary, ptr,
               MEMMOVE(ptr + beg + rlen, ptr + beg + len,
                   VALUE, olen - (beg + len)));
        ARY_SET_LEN(ary, alen);
    }
    if (rlen > 0) {
        MEMMOVE(RARRAY_PTR(ary) + beg, RARRAY_CONST_PTR(rpl), VALUE, rlen);
    }
    }
    RB_GC_GUARD(rpl);
}
rb_ary_插入(int-argc,VALUE*argv,VALUE-ary)
{
长pos;
rb_校验(argc,1,无限参数);
rb\U ary\U修改检查(ary);
如果(argc==1)返回ary;
pos=NUM2LONG(argv[0]);
如果(位置==-1){
pos=RARRAY_LEN(ary);
}
如果(位置<0){
pos++;
}
rb_ary_拼接(ary,pos,0,rb_ary_new4(argc-1,argv+1));
回归分析;
}
rb_ary_拼接(值ary、长beg、长len、值rpl)
{
龙乐伦;
长橄榄油;
如果(len<0)rb_升高(rb_eIndexError,“负长度(%ld)”,len);
olen=RARRAY_LEN(ary);
if(beg<0){
beg+=olen;
if(beg<0){
rb_raise(rb_eIndexError,“索引%ld对于数组太小;最小值:%ld”,
beg-olen,-olen);
}
}
if(olen=olen){
价值目标;
如果(beg>ARY_最大尺寸-rlen){
rb_升高(rb_eIndexError,“索引%ld太大”,beg);
}
target_ari=ari_确保_push(ari,rlen len)的空间;/*len为0或负*/
len=beg+rlen;
ary_mem_clear(ary、olen、beg-olen);
如果(rlen>0){
ary_memcpy0(ary、beg、rlen、RARRAY_CONST_PTR(rpl)、target_ary);
}
ARY_SET_LEN(ARY,LEN);
}
否则{
龙阿伦;
如果(olen-len>ARY_MAX_SIZE-rlen){
rb_raise(rb_EINDEXERR,“索引%ld太大”,olen+rlen-len);
}
rb_ary_modify(ary);
alen=olen+rlen-len;
如果(alen>=ARY_CAPA(ARY)){
ary_double_capa(ary,alen);
}
如果(len!=rlen){
RARRAY_PTR_使用(ary,PTR,
MEMMOVE(ptr+beg+rlen,ptr+beg+len,
值,olen-(beg+len));
ARY_SET_LEN(ARY,alen);
}
如果(rlen>0){
MEMMOVE(RARRAY_PTR(ari)+beg、RARRAY_CONST_PTR(rpl)、VALUE、rlen);
}
}
RB_GC_防护装置(rpl);
}
以下是MEMMOVE函数的参考:

TL;DR将项目追加(插入的一种特殊形式)到数组末尾通常在O(1)个时间内完成。

让我们浏览一下(MRI)ruby源代码,看看为什么会出现这种情况。我们从这行ruby代码开始:

a = [1,2]
Ruby准备一个数组对象,然后在中初始化它。 检查参数的有效性,然后使用以下命令检查数组的有效性:

ary_resize_capa(ary, len);
数组的容量是数组在从操作系统分配的内存块中可能容纳的元素数。 数组的长度(数组实际包含的元素数)始终小于或等于容量。 通过设置数组的容量,ruby确保分配足够的内存来容纳
len
数组中的项数

现在,让我们在数组的末尾添加一个元素:

a << 3
这个代码看起来不太吓人。它发现新元素的索引(
idx
)是数组的长度,确保数组有足够的内存容纳新元素(),将新元素写入数组,并增加数组长度

当阵列的容量大于其长度时,无需在
ari\u确保\u空间中为\u p分配更多内存
static VALUE
ary_ensure_room_for_push(VALUE ary, long add_len)
{
    long old_len = RARRAY_LEN(ary);
    long new_len = old_len + add_len;
    long capa;

    // ...

    rb_ary_modify(ary);
    capa = ARY_CAPA(ary);
    if (new_len > capa) {
        ary_double_capa(ary, new_len);
    }

    return ary;
}