免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2854 | 回复: 8
打印 上一主题 下一主题

插入位置问题. [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-07 11:58 |只看该作者 |倒序浏览
vector<**> a,b;
......
.....
.....
a.insert(a.begin(),b.begin(),b.end());
在像a插入时,为何是a.begin(),insert(X,Y,Z)函数插入位置应该是X位置的前一个.
在a.begin()位置的前一个应该为未定义啊??

论坛徽章:
0
2 [报告]
发表于 2007-07-07 13:18 |只看该作者
原帖由 gldamao 于 2007-7-7 11:58 发表
vector a,b;
......
.....
.....
a.insert(a.begin(),b.begin(),b.end());
在像a插入时,为何是a.begin(),insert(X,Y,Z)函数插入位置应该是X位置的前一个.
在a.begin()位置的前一个应该为未定义啊??

哪里规定是这样子的了?应该是从a.begin这个位置开始插入的

论坛徽章:
0
3 [报告]
发表于 2007-07-07 15:15 |只看该作者
原帖由 gldamao 于 2007-7-7 11:58 发表
vector a,b;
......
.....
.....
a.insert(a.begin(),b.begin(),b.end());
在像a插入时,为何是a.begin(),insert(X,Y,Z)函数插入位置应该是X位置的前一个.
在a.begin()位置的前一个应该为未定义啊??

从X位置开始的旧数据往后移动,新的数据放在空出来的空间里。

论坛徽章:
0
4 [报告]
发表于 2007-07-07 17:38 |只看该作者
原帖由 zwylinux 于 2007-7-7 13:18 发表

哪里规定是这样子的了?应该是从a.begin这个位置开始插入的

C++ primer第四版关于顺序容器的部分
自己查去,明确说了是从X位置之前插入的。

论坛徽章:
0
5 [报告]
发表于 2007-07-07 20:16 |只看该作者
原帖由 gldamao 于 2007-7-7 11:58 发表
vector a,b;
......
.....
.....
a.insert(a.begin(),b.begin(),b.end());
在像a插入时,为何是a.begin(),insert(X,Y,Z)函数插入位置应该是X位置的前一个.
在a.begin()位置的前一个应该为未定义啊??


不,不是未定义,因为 a.begin() 是一个合法的“位置”。

insert(X,Y,Z) 应该理解为在 X 所在(或所指)的元素之前插入。

论坛徽章:
0
6 [报告]
发表于 2007-07-07 22:55 |只看该作者
看了一下SGI的源码:


  1. template <class T, class Alloc>
  2. void vector<T, Alloc>::insert(iterator position, size_type n, const T& x) {
  3.   if (n != 0) {
  4.     if (size_type(end_of_storage - finish) >= n) {
  5.       T x_copy = x;
  6.       const size_type elems_after = finish - position;
  7.       iterator old_finish = finish;
  8.       if (elems_after > n) {
  9.         uninitialized_copy(finish - n, finish, finish);
  10.         finish += n;
  11.         copy_backward(position, old_finish - n, old_finish);
  12.         fill(position, position + n, x_copy);
  13.       }
  14.       else {
  15.         uninitialized_fill_n(finish, n - elems_after, x_copy);
  16.         finish += n - elems_after;
  17.         uninitialized_copy(position, old_finish, finish);
  18.         finish += elems_after;
  19.         fill(position, old_finish, x_copy);
  20.       }
  21.     }
  22.     else {
  23.       const size_type old_size = size();        
  24.       const size_type len = old_size + max(old_size, n);
  25.       iterator new_start = data_allocator::allocate(len);
  26.       iterator new_finish = new_start;
  27.       __STL_TRY {
  28.         new_finish = uninitialized_copy(start, position, new_start);
  29.         new_finish = uninitialized_fill_n(new_finish, n, x);
  30.         new_finish = uninitialized_copy(position, finish, new_finish);
  31.       }
  32. #         ifdef  __STL_USE_EXCEPTIONS
  33.       catch(...) {
  34.         destroy(new_start, new_finish);
  35.         data_allocator::deallocate(new_start, len);
  36.         throw;
  37.       }
  38. #         endif /* __STL_USE_EXCEPTIONS */
  39.       destroy(start, finish);
  40.       deallocate();
  41.       start = new_start;
  42.       finish = new_finish;
  43.       end_of_storage = new_start + len;
  44.     }
  45.   }
  46. }
复制代码


仅以这三行来说明问题:
        new_finish = uninitialized_copy(start, position, new_start);
        new_finish = uninitialized_fill_n(new_finish, n, x);
        new_finish = uninitialized_copy(position, finish, new_finish);

当start = position的时候,其实第一行代码是不起作用的,因此新插入的元素是插入在begin的前面了。

论坛徽章:
0
7 [报告]
发表于 2007-07-08 09:11 |只看该作者
我也是说插入在begin的前面,但是我不理解begin()前面是什么东西。给我的感觉就好像是
int a[3];
a[-1]=2;
难道访问不越界吗?
在插入到X之前以后,原来的X.begin()是不是就在。x.begin()+1的位置上了。

论坛徽章:
0
8 [报告]
发表于 2007-07-08 12:51 |只看该作者
原帖由 gldamao 于 2007-7-8 09:11 发表
我也是说插入在begin的前面,但是我不理解begin()前面是什么东西。给我的感觉就好像是
int a[3];
a[-1]=2;
难道访问不越界吗?
在插入到X之前以后,原来的X.begin()是不是就在。x.begin()+1的位置上了。

那你觉得a.insert(a.begin() + 1,b.begin(),b.end());能理解吗?这岂不成了:
int a[3] = { 1, 3 };
a[1] = 2;

原来的a[1]跑哪儿去了?正确的做法是先把a[1]后移一位,然后再赋值:
a[2] = a[1];
a[1] = 2;

vector会做同样的事,只不过你只需要调用vector提供的insert函数,具体移动数据的细节会由vector自行管理。vector虽然底层是用数组实现的,但使用的时候可以把它当成完全动态的,你可以在它的前面、后面、中间任意插入数据。就像链表一样。

但是需要注意一下因为底层是用静态数组实现的,所有某些操作会非常耗费资源。比如你插入数据时,vector会把插入位置之后的所有数据后移一段位置,空出来空间存放新的数据(如果原来的数组空间不够,就需要重新申请一个更大的数组,这就更耗费资源了)。如果你从begin位置开始插入,则整个数组都会后移,给新的数据空出来空间。

vector不适合需要频繁插入、删除数据的应用。

论坛徽章:
0
9 [报告]
发表于 2007-07-09 11:32 |只看该作者
说的好
基本理解了
不知道这个论坛有没有结贴的设置
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP