前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >STL之序列式容器(array和vector)

STL之序列式容器(array和vector)

作者头像
用户9831583
发布2022-06-16 14:37:05
5910
发布2022-06-16 14:37:05
举报
文章被收录于专栏:码出名企路
array

array<T,N> : 一个有 N 个 T 类型元素的固定序列。除了需要指定元素的类型和个数之外,和常规数组没有太大的差别。显然,不能增加或删除元素。

1.初始化

代码语言:javascript
复制
#include <array>
#include <iostream>
using namespace std;
int main()
{
    std::array<double,100> data;
    std::array<double, 100> data1 {};
    std::array<double, 10> values {0.5, 1.0, 1.5, 2.0};
    //通过调用数组对象的成员函数 fill(),可以将所有元素设成给定值
    values.fill(3.1415926);
 
   //不检查越界
    values[4] = values[3] + 2.O*values[1];
   //检查越界
    values.at (4) = values.at(3) + 2.O*values.at(1);

    double total {};
    for(auto&& value : values)
         total += value;
    std::array<std::string, 5> words {"one","two","three”,"four","five" };
    std::cout << std::get<3>(words) << std::endl; // Output words[3]
    std::cout << std::get<6>(words) << std::endl; // Compiler error message!

    return 0;
}

2.访问元素

代码语言:javascript
复制
#include <iostream> // For standard streams
#include <iomanip>  // For stream manipulators
#include <array>    // For array<T,N>
int main()
{
    const unsigned int min_wt {100U};
    const unsigned int max_wt {250U};
    const unsigned int wt_step {10U};
    const size_t wt_count {1 + (max_wt - min_wt) / wt_step};
    const unsigned int min_ht {48U};
    const unsigned int max_ht {84U};
    const unsigned int ht_step {2U};
    const size_t ht_count { 1 + (max_ht - min_ht) / ht_step };
    const double lbs_per_kg {2.20462};
    const double ins_per_m {39.3701};
    std::array<unsigned int, wt_count> weight_lbs;
    std::array<unsigned int, ht_count> height_ins;
    // Create weights from lOOlbs in steps of lOlbs
    for (size_t i{}, w{min_wt} ; i < wt_count ; w += wt_step, ++i)
    {
        weight_lbs.at(i) = w;
    }
    //Create heights from 48 inches in steps of 2 inches
    unsigned int h{min_ht};
    for(auto& height : height_ins)
    {
        height = h;
        h += ht_step;
    }
    //Output table headings
    std::cout << std:: setw (7) <<" |";
    for (const auto& w : weight_lbs)
        std::cout << std:: setw (5) << w<<"11";
    std::cout << std::endl;
    // Output line below headings
    for (size_t i{1} ; i < wt_count ; ++i)
        std::cout<<"---------";
    std::cout << std::endl;
    double bmi {};
    unsigned int feet {};
    unsigned int inches {};
    const unsigned int inches_per_foot {12U};
    for (const auto& h : height_ins)
    {
        feet = h / inches_per_foot;
        inches = h % inches_per_foot;
        std::cout << std::setw (2) <<feet <<"'"<<std::setw (2) << inches <<"\""<<"|";
        std::cout << std::fixed <<std::setprecision(1);
        for (const auto& w : weight_lbs)
        {
            bmi = h / ins_per_m;
            bmi = (w / lbs_per_kg) / (bmi*bmi);
            std::cout << std:: setw (2) <<""<<bmi <<" |";
        }
        std::cout << std::endl;
    }
    for (size_t i {1} ; i < wt_count ; ++i)
        std::cout << "---------";
    std::cout << "\nBMI from 18.5 to 24.9 is normal" << std::endl;
}

3.迭代器

代码语言:javascript
复制
#include <iostream> // For standard streams
#include <iomanip>  // For stream manipulators
#include <array>    // For array<T,N>
#include <algorithm>//geberate
#include <numeric>//itoa
using namespace std;

int main()
{
    array<double,5> height_ins{1,2,3,4,5};
    
    unsigned int h {100U};
    int ht_step=1,min_ht=0;
    auto first = height_ins.begin();
    auto last = height_ins.end () ;
    while (first != last)
    {
        *first++=h;
        h += ht_step;
    }

    //全局访问
   // auto first = std::begin(height_ins);
   // auto last = std::end (height_ins);

    //lamba
        unsigned int height {};
    std::generate(std::begin(height_ins), std::end(height_ins),
        [height, &min_ht, &ht_step]()mutable{ return height += height == 0 ? min_ht : ht_step; });

        std::array<double, 10> values;
std::iota(std::begin(values), std::end(values),10.0);

//全局函数或成员函数 rbegin() 和 rend() 可以分别得到指向最一个元素和第一个元素前一个位置的反向迭代器。
//函数 crbegin() 和 crend() 可以返回 const 反向迭代器。
    std::array<double, 5> these {1.0, 2.0, 3.0, 4.0, 5.0};
    double sum {};
    auto start = these.rbegin();
    auto finish = these.rend();
    while(start != finish)
        sum += *(start++);
    std::cout << "The sum of elements in reverse order is " << sum << std::endl;

    return 0;
}

4.比较大小

代码语言:javascript
复制
    //元素比较
    //对 ==,如果两个数组对应的元素都相等,会返回 true。对于 !=,两个数组中只要有一个元素不相等,就会返回 true
      std::array<double,4> these {1.0, 2.0, 3.0, 4.0};
    std::array<double,4> those {1.0, 2.0, 3.0, 4.0};
    std::array<double,4> them {1.0, 3.0, 3.0, 2.0};
    if (these == those) std::cout << "these and those are equal." << std::endl;
    if (those != them) std::cout << "those and them are not equal."<< std::endl;
    if (those < them) std::cout << "those are less than them."<< std::endl;
    if (them > those) std::cout << "them are greater than those." << std::endl;
vector

vector<T> : 包含 T 类型元素的序列容器,容器的大小可以自动增长,从而可以包含任意数量的元素。

1.初始化

代码语言:javascript
复制
#include <vector>
#include <iostream>
using namespace std;
#include <array>    // For array<T,N>
int main()
{
    std::vector<double> values;
    values.reserve(20);//这样就设置了容器的内存分配,至少可以容纳 20 个元素。

    std::vector<unsigned int> primes {2u, 3u, 5u, 7u, 11u, 13u, 17u, 19u};
    std::vector<double> values(20);//使用初始元素个数来生成 vector 容器:
    std::vector<double> values {20};//vector 并没有 20 个元素。它只有一个元素,并以 20 作为初始值。
    //添加元素会导致分配额外的内存。

    //第二个参数指定了所有元素的初始值,因此这 20 个元素的值都是 99L。
    //第一个元素指定了 vector 中的元素个数
    std::vector<long> numbers(20, 99L);

    //可以用元素类印相同的容器来初始化 vector<T> 容器。用一对迭代器来指定初始值的范围。
    std::array<std :: string, 5> words {"one", "two","three", "four", "five"};
    std::vector<std::string> words_copy {std::begin(words) , std::end(words)};
    
    std::vector<std::string〉 words_copy {std::make_move_iterator
            (std::begin(words)),std::make_move_iterator(std:: end(words))};
}

2.容量大小

代码语言:javascript
复制
//vector 的容量大小,是指在不分配更多内存的情况下可以保存的最多元素个数,
//这时 可能有 20 个元素,也可能没有。
//vector 的大小是它实际所包含的元素个数,也就是有值的元素的个数

    std::vector<size_t> primes { 2, 3, 5, 7, 11, 13, 17, 19, 23,
            29, 31, 37, 41 ,43 ,47 };
    std::cout << "The size is " << primes.size() << std::endl;
    std::cout << "The capacity is" << primes.capacity() << std::endl;
//输出语句输出的容器大小和容董都为 15,这是由初始化列表决定的。然而,如果用 push_back() 函数添加一个元素,
//然后再输出容器的大小和容量,这时大小变为 16,容量变为 30。

    auto nElements = primes.size();
    for(auto& prime : primes)
        prime *= 2;

//第一个 resize() 调用会把元素的个数变为参数指定的值,所以会增加两个用默认值初始化的元素。如果添加了一个元素,导致超过当前容器的容景,容量会自动增加。
//第二个 resize() 调用将元素增加到第一个参数指定的个数,并用第二个参数初始化增加的新元素。
//第三个 resize() 凋用将容器大小设为 6,小于当前元素的个数。当需要减小容器的大小时,会移除多余的元素,这就好像重复调用了几次 pop_back() 函数。
    std::vector<int> values {1,2,3};
    values.resize (5);
    values.resize (7, 99);
    values.resize (6);

3.插入元素

代码语言:javascript
复制
//emplace() 的第一个参数是一个迭代器,它确定了对象生成的位置。
//对象会被插入到迭代器所指定元素的后面。第一个参数后的参数,都作为插入元素的构造函数的参数传入。
    std::vector<std::string> words {"first", "second"};
    // Inserts string(5,'A') as 2nd element
    auto iter = words.emplace(++std::begin(words),5,'A');
    //Inserts string ("$$$$") as 3rd element
    words.emplace(++iter, "$$$$");

    //成员函数 insert() 可以在 vector 中插入一个或多个元素。第一个参数总是一个指向插入点的 const 或 non-const 迭代器。
    //元素会被迅速插入到第一个参数所指向元素的前面,如果第一个参数是一个反向迭代器,元素会被插入到迭代器所指向元素的后面。
   std::vector<std::string> words { "one","three","eight"} //Vector with 3 elements
   auto iter = words.insert(++std::begin(words), "two");//"one" "two" "three" "eight"

  std:: string more[] {"five", "six", "seven" }; // Array elements to be inserted
   iter = words.insert(--std::end(words) , std::begin(more),    std::end(more));//"one" "two" "three" "five" "six" "seven" "eight"

   iter = words.insert(std::end(words), "ten");//"one" "two" "three" "five" "six" "seven" "eight" "ten"

   iter = words.insert(std::cend(words)-1, 2, "nine");//"one" "two" "three" "five" "six" "seven" "eight" "nine" "nine" "ten"

   iter = words.insert(std::end(words), {std::string {"twelve"},std::string {"thirteen"}});
   //"one" "two" "three" "five" "six" "seven" "eight" "nine" "nine" "ten" "twelve" "thirteen"

//find() 算法会在头两个参数所指定的一段元素中,搜索第三个参数指定的元素,返回第一个找到的元素,因此会找到 String("one")。
       std::vector<std::string> str { "one", "two", "one", "three"};
    auto riter = std::find(std::rbegin(str), std::rend(str) , "one");
    str.insert(riter.base(), "five");//"one", "two", "one", "five", "three"

4.迭代器

代码语言:javascript
复制
    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <vector>
    #include<iterator>
    using std::string;
    using std::vector;
    using namespace std;
    int main()
    {
        vector<string> words;                     // Stores words to be sorted
        words.reserve(10);                        // Allocate some space for elements
        std::cout << "Enter words separated by spaces. Enter Ctrl+Z on a separate line to end:" << std::endl;
        std::copy(std::istream_iterator <string> {std::cin},
         std::istream_iterator <string> {},std::back_inserter(words));
        std::cout << "Starting sort." << std::endl;
        bool out_of_order {false};
        while (true)
        {
            for (auto first = words.begin() + 1; first != words.end(); ++first)
            {
                if (*(first - 1) > *first)
                { // Out of order so swap them
                    std::swap(*first, *(first - 1));
                    out_of_order = true;
                }
            }
            if (!out_of_order)                      // If they are in order (no swaps necessary)...
                break;                                // ...we are done...
            out_of_order = false;                   // ...otherwise, go round again.
        }
        std::cout << "your words in ascending sequence:" << std::endl;
        std::copy(std::begin(words), std::end(words), std::ostream_iterator < string > {std::cout, " "});
        std::cout << std::endl;
        // Create a new vector by moving elements from words vector
        vector<string> words_copy {std::make_move_iterator(std::begin(words)),std::make_move_iterator(std::end(words))};
        std::cout << "\nAfter moving elements from words, words_copy contains:" << std::endl;
        std::copy(std::begin(words_copy), std::end(words_copy),  std::ostream_iterator < string > {std::cout, " "});
        std::cout << std::endl;
        // See what's happened to elements in words vector...
        std::cout << "\nwords vector has " << words.size() << " elements\n";
        if (words.front().empty())
        std::cout << "First element is empty string object." << std::endl;
        std::cout << "First element is \"" << words.front() << "\"" << std::endl;
    }

5.访问元素

代码语言:javascript
复制
    std::vector<double> values (20);
    values[0] = 3.14159;
    values[1] = 5.0;
    values[2] = 2.0*values[0]*values[1];
//vector 的成员函数 front() 和 back() 分別返回序列中第一个和最后一个元素的引用,
    std::cout << values.front () << std::endl; // Outputs 3.14159

    //成员函数 data() 返回一个指向数组的指针,它在内部被用来存储元素
    //pData 是 double* 类型,一般来说,data() 返回 vector<T> 容器的 T* 类型的值。
        auto pData = values.data();

6.删除元素

代码语言:javascript
复制
    std::vector<int> data(100, 99);// Contains 100 elements initialized to 99
    data.clear(); // Remove all elements 所以容量还是 100。

    std::vector<int> data(100, 99); // Contains 100 elements initialized to 99
    data.pop_back(); // Remove the last element

   //假设要删除 data 中的第二个元素
        std::swap(std::begin(data)+1,std::end(data)-1);
         data.pop_back();
    // Interchange 2nd element with the last data.pop_back(); // Remove the last element

    //如果要去掉容器中多余的容量,例如不再向容器中添加新元素,那么可以通过使用成 员函数 shrink_to_fit() 来实现:
data.shrink_to_fit(); // Reduce the capacity to that needed for elements
auto iter = data.erase(std::begin(data)+1); //Delete the second element它指向被删除元素后的一个元素

    // Delete the 2nd and 3rd elements
    auto iter = data.erase(std::begin(data)+1,std::begin(data)+3);//第二个迭代器指向这段元素末尾的下一个位置

//如果在 remove() 操作后输出 words 中的元素,只会输出前 5 个元素。尽管 size() 返回的值仍然是 7,
//而且最后两个元素仍然存在,但是它们被替换成了空字符串对象。
std::vector<std::string> words { "one", "none","some", "all”, "none", "most","many"};
auto iter = std::remove(std::begin(words), std::end(words), "none");
words.erase(iter, std::end(words));//Remove surplus elements

erase-remove,执行删除操作后,iter 指向最后一个元素之后的位置,
所以它标识了被删除序列的第一个元素,被删除序列的结束位置由 std::end(words) 指定
words.erase(std::remove(std::begin(words), std::end(words),"none"), std::end(words));
代码语言:javascript
复制
    // Understanding how capacity is increased in a vector container
    #include <iostream>                             // For standard streams
    #include <vector>                               // For vector container
    int main()
    {
        std::vector <size_t> sizes;                    // Record numbers of elements
        std::vector <size_t> capacities;               // and corresponding capacities
        size_t el_incr {10};                           // Increment to initial element count
        size_t incr_count {4 * el_incr};               // Number of increments to element count
         for (size_t n_elements {}; n_elements < incr_count; n_elements += el_incr)
        {
            std::vector<int> values(n_elements);
            std::cout << "\nAppending to a vector with " << n_elements << " initial elements:\n";
            sizes.push_back(values.size());
            size_t space {values.capacity()};
            capacities.push_back(space);
            // Append elements to obtain capacity increases
            size_t count {};                             // Counts capacity increases
            size_t n_increases {10};
            while (count < n_increases)
            {
                values.push_back(22);                      // Append a new element
                if (space < values.capacity())             // Capacity increased...
                {                                            // ...so record size and capacity
                    space = values.capacity();
                    capacities.push_back(space);
                    sizes.push_back(values.size());
                    ++count;
                }
            }
            // Show sizes & capacities when increments occur
            std::cout << "Size/Capacity: ";
            for (size_t i {}; i < sizes.size(); ++i)
                std::cout << sizes.at(i) << "/" << capacities.at(i) << "  ";
            std::cout << std::endl;
            sizes.clear();                               // Remove all elements
            capacities.clear();                          // Remove all elements
        }
    }

7.增加元素

代码语言:javascript
复制
  std::vector<double> values;

 values.push_back(3.1415926);

  std::vector<std::string> words;

words.push_back(string("adiabatic"));

/ Move string("adiabatic") into the vector

 words.push_back ("adiabaticft"); // Move string("adiabatic")

   // emplace back() 比 push_back() 更有效率

    std::vector<std::string> words;
  words.push_back (std:: string ("facetious") ) ; // Calls string constructor & moves the string object

  words•emplace_back("abstemious");// Calls string constructor to create element in place

   // emplace_back() 函数会调用接收三个参数的 string 构造函数,生成 string 对象,

   // 然后把它添加到 words 序列中。构造函数会生成一个从索引 2 幵始、包含 str 中三个字符的子串。

  std::string str {"alleged"};

 words.emplace_back(str, 2, 3);

  // Create string object corresponding to "leg" in place
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码出名企路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • array
  • vector
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档