zoukankan      html  css  js  c++  java
  • C++STL模板库序列容器之vector

    STL之Vecter

    一丶STL简介

    STL 是标准模板库的意思. 就是数据结构,封装成类让我们使用. 使用的时候我们要了解数据结构才可以使用这些类.因为数据结构不知道是什么结构你用类的话也用不明白.

    二丶Vector用法

    1.vector容器的使用

    首先介绍的第一个序列容器就是 vector. 它底层是数组.可以理解为是动态数组.
    我们自己也可以写一个动态数组.然后 将运算符[] 进行重载.
    使用之前需要包含头文件,以及使用命名空间.std. 类是在这里面定义的.

     #include<vector>
    using namespace std;
    

    因为是动态数组.所以vector容器操作的都是尾部操作.就也是数组后面进行增删改查.

    2.vector迭代器.

    vector的迭代器有两种.

    vector<object>::const_iterator  const_iterator迭代器是不能修改内容的
    vector<object>::iterator   iterator定义的迭代器是可读可写的.
    

    编写代码如下:
    栈代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string>
    #include <vector>
    #include <iostream>
    using namespace std;
    int main(char *argc,char *argv[]) 
    {
    
    	vector<int> a;
    	a.push_back(1);
    	a.push_back(2);
    
    	vector<int>::const_iterator it = a.begin();
    	while (it != a.end()) 
    	{
    		cout << *it << endl;
    		++it;
    	}
    	system("pause");
    
    }
    

    方法:
    push_back(Value); 是往数组后面添加值.
    begin(); 获取第一个元素
    end(); 获取最后一个元素.

    *it 获取值.
    上面的代码使我们存放的int类型数据. 其实vector可以当做数组来用.是变长的数组.
    跨平台的. 我们不光可以存储int 也可以存储 基本类型.以及指针类型都是可以的.或者存储
    函数指针也可以.
    例如下:

    typedef int(*pFn)(int , int );
    int Add(int a, int b)
    {
    	return a + b;
    }
    int main(char *argc,char *argv[]) 
    {
    	pFn p = Add;
    	vector<pFn> pfnve;
    	pfnve.push_back(p);
    	vector<pFn>::iterator it = pfnve.begin();
    	while (it != pfnve.end())
    	{
    		cout << (*it)(1, 2) << endl; //第一种输出方式
    		cout << it[0](1, 4) << endl; //使用[]操作符输出
    		it++;
    	}
    	system("pause");
    
    }
    

    结果第一个会输出3,第二个会输出五,因为我们存储了一个函数指针.如果存储多个.则可以进行多次调用.
    堆代码:
    上面使用的 vector是在栈中定义的,我们也可以定义为指针.也就是在堆中使用.
    代码如下:

    int main(char *argc,char *argv[]) 
    {
    	vector<int> *a = new vector<int>;
    	a->push_back(1);
    	a->push_back(2);
    	a->push_back(4);
    	a->push_back(3);
    	a->push_back(5);
    
    	vector<int>::const_iterator it = a->cbegin();
    	while (it != a->cend())
    	{
    		cout << (*it) << endl;
    		cout << it[0] << endl;
    		it++;
    	}
    	cout << "---------------------------" << endl;
    
    	system("pause");
    
    }
    
    

    cbegin(); 也是返回第一个元素,前提是你使用const_iterator 迭代器才可以. cbegin()c开头就是const的意思.常量的意思.也就是说不能更改.

    3.vector中的方法.

    push_back(Value); 往vector容器后面添加一个数据.
    begin(); 获取第一个元素.
    end(); 标记容器的最后一个元素.只代表结束标记.
    int size(); 容器中元素的个数,可以通过 for(i < xx.size());的方式遍历
    void clear(); 清空容器中的所有元素
    Object front(); 返回容器中第一个元素的值,跟begin()不同,它是返回值
    Object back(); 返回容器中最后一个元素的值
    void pop_back(); 清空最后一个元素,需要配合back();否则除非你不需要最后一个元素.
    erase(); 删除容器中任意一个位置的元素.

    三丶常用算法

    算法是单独在一个头文件中,我们可以使用算法配合vector容器进行写程序
    包含头文件

    #include <algorithm>
    

    1.常见算法中的算法方法.

    sort(); 排序
    reverse(); 反转
    find(); 查找
    copy(); 拷贝

    2.sort()方法的使用

    int main(char *argc,char *argv[]) 
    {
    	vector<int> *a = new vector<int>;
    
    	srand((unsigned long)time(0)); //随机化种子
    	for (int i = 0; i < 10; i++)
    	{
    		a->push_back(rand() % 100); //从0 - 99 中随机取出一个数字放到容器中
    	}
    	//进行排序
    	sort(a->begin(), a->end());
    	
    	//输出结果
    	vector<int>::const_iterator it = a->cbegin();
    	while (it != a->cend())
    	{
    		cout << " " << (*it) ;
    		it++;
    	}
    	
    	cout << endl <<  "---------------------------" << endl;
    
    	system("pause");
    
    }
    
    

    使用time srand() rand() 函数的时候,需要包含头文件time.h.
    输出结果:

    上面使用的sort()排序是默认从小到大的.那么我们想要从大到小怎么办.
    此时STL中算法sort()方法规定了.你定义一个compare函数.当做第三个参数传入进来即可.
    compare是你自己编写的比较方式.
    代码如下:

    
    bool compare(int a, int b)
    {
    	if (a < b)
    		return true;
    	return false;
    }
    返回值必须是bool  函数名无所谓.参数也无所谓.你如果是int类型的容器.就是用int判断.其它类型就是用其它类型判断.
    
    
    原代码不动,只需要改动sort();方法即可.
    sort(a->begin(), a->end(), compare);
    

    程序运行结果:

    3.find()方法使用

    find()方法是一个查找返回,返回查找到的标记的位置. 也就是说是一个迭代器接受查找到的位置.
    代码如下:
    find(迭代器开始标记,迭代器结束标记,你要查找的值);
    找到了返回 位置. 没有找到.返回结束标记;

     vector<int>::iterator it = find(a->begin(), a->end(),11);
    
       if (it != a->cend())
       {
        cout << " find Value " << (*it);
       }
       else
       {
         cout << "Not Find" << endl;
       }
    

    只贴出核心代码.主要介绍Find函数.

    4.删除容器中的元素

    这里主要使用find函数配合进行删除,查找到在删除
    核心代码

    vector<int>::iterator it = find(a->begin(), a->end(),11);
    
       if (it != a->cend())
       { 
    	  a->erase(it);
       }
       else
       {
         cout << "Not Find" << endl;
       }
    
    

    erase();函数,可以删除容器中的指定的元素.但是删除之后.元素内容会自动进行+1.也就是指向了下一个位置. 此时我们需要--
    例如如下代码:

     vector<int>::iterator it = a->begin();
      while (it != a->end())
      {
        cout << *it << endl;
        if (*it == 7) 
    	{
          a->erase(it); //这里可以删除,但是内部it会指向下一个元素.所以我们需要进行it--才可以使程序正确
          it--; //注意这个地方.
          cout << "删除成功" << endl;
        }
        it++;
      }
    
    

    三丶vector操作类或者结构体

    代码如下:

    typedef struct _PersonInfo
    {
      char szName[20];
      int age;
      float height;
    }PersonInfo ,*PPersonInfo;
    
    int main(char *argc, char *argv[]) {
     
    	//定义两种类型迭代器.保存结构体,以及结构体指针的迭代器
      vector<PersonInfo> one;//保存结构体
      vector<PPersonInfo> two;//保存结构体指针
      PersonInfo p1 = { "tom", 14, 1.76f };
      PPersonInfo p2 = new PersonInfo; //指针的话必须申请内存
      strncpy(p2->szName, "李四", 20); //指针的话使用函数拷贝
      p2->age = 15;
      p2->height =  1.59f;
    
      //使用容器进行存储
      one.push_back(p1); 
      two.push_back(p2); //存储指针
    
      //进行迭代
      vector<PersonInfo>::iterator it1 = one.begin();
      while (it1 != one.end())
      {
        cout << it1->szName << " " << it1->age << " " << it1->height << endl; //输出的时候使用->指向箭头输出. 或者 it[i].name方式
        it1++;
      }
      //对指针进行迭代.
      cout << "-----------------------------" << endl;
      vector<PPersonInfo>::iterator it2 = two.begin();
      while (it2 != two.end())
      {
        cout << (*it2)->szName << " " << (*it2)->age << " " << (*it2)->height
             << endl;
        it2++;
      }
      system("pause");
    }
    

    总结一下: 操作结构体跟操作类是一样的. 迭代的时候.我们可以用->运算符直接取值. 如果是存储指针.
    那么我们就要 (*it)->member 方式去操作了.

  • 相关阅读:
    AIX上Oracle安装10204补丁出现写文件错误
    Oracle自定义函数
    表中最大分区数
    查询RMAN资料库——RMAN用户手册
    查询访问同一表的两个以上索引(三)
    管理RMAN资料库——RMAN用户手册
    查询访问同一表的两个以上索引(一)
    DDL语句为什么不能回滚
    JDBC运行出现ORA17410错误
    MySQL数据库操作类(转)
  • 原文地址:https://www.cnblogs.com/iBinary/p/9885692.html
Copyright © 2011-2022 走看看