Sequence Containers

Implement data structures which can be accessed in a sequential manner

std::vector

template < class T, class Alloc = allocator > class vector;
header

Member function

begin
end
rbegin Return reverse iterator to reverse beginning
rend Return reverse iterator to reverse end
cbegin
cend
crbegin
crend
size
max_size Return maximum size
resize
capacity
empty
reserve
erase iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);
myvec.erase(myvector.begin() + 5)
myvec.erase(myvector.begin(), myvector.begin() + 5)
operator[] Access element
at Access element
front Access first element
back Access last element
data
assign
push_back Add element at the end
pop_back Delete last element
insert iterator insert(const_iterator position, const value_type& val); Insert elements
swap void swap (vector& x); Swap content
std::vectorfoo(3,100);
std::vectorbar(5,200);
foo.swap(bar);
clear Clear content
  1. // inserting into a vector
  2. #include <iostream>
  3. #include <vector>
  4. int main ()
  5. {
  6. std::vector<int> myvector (3,100);
  7. std::vector<int>::iterator it;
  8. it = myvector.begin();
  9. it = myvector.insert ( it , 200 );
  10. myvector.insert (it,2,300);
  11. // "it" no longer valid, get a new one:
  12. it = myvector.begin();
  13. std::vector<int> anothervector (2,400);
  14. myvector.insert (it+2,anothervector.begin(),anothervector.end());
  15. int myarray [] = { 501,502,503 };
  16. myvector.insert (myvector.begin(), myarray, myarray+3);
  17. std::cout << "myvector contains:";
  18. for (it=myvector.begin(); it<myvector.end(); it++)
  19. std::cout << ' ' << *it;
  20. std::cout << '\n';
  21. return 0;
  22. }
  23. //myvector contains: 501 502 503 300 300 400 400 200 100 100 100

Container Adaptors

Provide a different interface for sequential containers

std::queue

template > class queue;
header

Member functions

empty bool empty() const; Test whether container is empty
Returns whether the queue is empty: i.e. whether its size is zero.
size size_type size() const; Return sizeReturns the number of elements in the queue.
front reference& front();
const_reference& front() const;
Access next element
Returns a reference to the next element in the queue.
The next element is the “oldest” element in the queue and the same element that is popped out from the queue when queue::pop is called.
back value_type& back();
const value_type& back() const;
Access last element
Returns a reference to the last element in the queue. This is the “newest” element in the queue (i.e. the last element pushed into the queue).
push void push (const value_type& val);
void push (value_type&& val);
Insert element
Inserts a new element at the end of the queue, after its current last element. The content of this new element is initialized to val.
emplace templatevoid emplace(Args&&… args); Construct and insert elementAdds a new element at the end of the queue, after its current last element. This new element is constructed in place passing args as the arguments for its constructor.
pop void pop(); Remove next element
Removes the next element in the queue, effectively reducing its size by one.
The element removed is the “oldest” element in the queue whose value can be retrieved by calling member queue::front.

This calls the removed element’s destructor.
swap void swap (queue& x) noexcept(/see below/) Swap contents
Exchanges the contents of the container adaptor (*this) by those of x.
This member function calls the non-member function swap (unqualified) to swap the underlying containers.

Example

  1. // CPP code to illustrate
  2. // Queue in Standard Template Library (STL)
  3. #include <iostream>
  4. #include <queue>
  5. using namespace std;
  6. void showq(queue <int> gq)
  7. {
  8. queue <int> g = gq;
  9. while (!g.empty())
  10. {
  11. cout << '\t' << g.front();
  12. g.pop();
  13. }
  14. cout << '\n';
  15. }
  16. int main()
  17. {
  18. queue <int> gquiz;
  19. gquiz.push(10);
  20. gquiz.push(20);
  21. gquiz.push(30);
  22. cout << "The queue gquiz is : ";
  23. showq(gquiz);
  24. cout << "\ngquiz.size() : " << gquiz.size();
  25. cout << "\ngquiz.front() : " << gquiz.front();
  26. cout << "\ngquiz.back() : " << gquiz.back();
  27. cout << "\ngquiz.pop() : ";
  28. gquiz.pop();
  29. showq(gquiz);
  30. return 0;
  31. }

std::stack

header
template > class stack;

Member Functions

empty
size
top
push
emplace
pop
swap

Associative Containers

Implement sorted data structures that can be quickly searched(O(log n) complexity)

std::map

header
template < class Key, // map::key_type
class T, // map::mapped_type
class Compare = less, // map::key_compare
class Alloc = allocator > // map::allocator_type
> class map;

Member Functions

begin
end
rbegin
rend
cbegin
cend
crbegin
crend
empty
size
max_size
operator[]
at
insert
erase iterator erase (const_iterator position);
size_type erase (const key_type& k);
iterator erase (const_iterator first, const_iterator last);
std::mapmymap;
mymap[‘a’]=10
it=mymap.find(‘a’)
mymap.erase(it)
mymap.erase(‘a’)
mymap.erase(it, mymap.end())
swap
clear
key_comp
value_comp
find
count
lower_bound
upper_bound
upper_bound
equal_range

std::set

header
template < class T, // set::key_type/value_type
class Compare = less, // set::key_compare/value_compare
class Alloc = allocator // set::allocator_type
> class set;

Member Functions

Unordered Associative Containers

implement unordered data structures that can be quickly searched

unordered_map

header
template >

unordered_set

unordered_map

unordered_multimap

Algorithm

std::sort

header
template void sort (RandomAccessIterator first, RandomAccessIterator last);
template void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

sort(first_iterator, last_iterator)

// sort algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector

bool myfunction (int i,int j) { return (i<j); }

struct myclass {
  bool operator() (int i,int j) { return (i<j);}
} myobject;

int main () {
  int myints[] = {32,71,12,45,26,80,53,33};
  std::vector<int> myvector (myints, myints+8);               // 32 71 12 45 26 80 53 33

  // using default comparison (operator <):
  std::sort (myvector.begin(), myvector.begin()+4);           //(12 32 45 71)26 80 53 33

  // using function as comp
  std::sort (myvector.begin()+4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)

  // using object as comp
  std::sort (myvector.begin(), myvector.end(), myobject);     //(12 26 32 33 45 53 71 80)

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

//output
//$ myvector contains: 12 26 32 33 45 53 71 80

std::reverse

To reverse a vector
header
reverse(first_iterator, last_iterator)

// A C++ program to demonstrate working of sort(), 
// reverse() 
#include <algorithm> 
#include <iostream> 
#include <vector> 
using namespace std; 

int main() 
{ 
    // Initializing vector with array values 
    int arr[] = {10, 20, 5, 23 ,42 , 15}; 
    int n = sizeof(arr)/sizeof(arr[0]); 
    vector<int> vect(arr, arr+n); 

    cout << "Vector is: "; 
    for (int i=0; i<n; i++) 
        cout << vect[i] << " "; 

    // Reversing the Vector 
    reverse(vect.begin(), vect.end()); 

    cout << "\nVector after reversing is: "; 
    for (int i=0; i<6; i++) 
        cout << vect[i] << " "; 

    return 0; 
}

std::max_element

To find the maximum element of a vector.
header
*max_element(first_iterator, last_iterator)

// A C++ program to demonstrate working of sort(), 
// reverse() 
#include <algorithm> 
#include <iostream> 
#include <vector> 
using namespace std; 

int main() 
{ 
    // Initializing vector with array values 
    int arr[] = {10, 20, 5, 23 ,42 , 15}; 
    int n = sizeof(arr)/sizeof(arr[0]); 
    vector<int> vect(arr, arr+n); 

    cout << "Vector is: "; 
    for (int i=0; i<n; i++) 
        cout << vect[i] << " "; 

    cout << "\nMaximum element of vector is: "; 
    cout << *max_element(vect.begin(), vect.end()); 

    return 0; 
}

std::min_element

To find the minimum element of a vector
header
*min_element(first_iterator, last_iterator)

// A C++ program to demonstrate working of sort(), 
// reverse() 
#include <algorithm> 
#include <iostream> 
#include <vector> 
using namespace std; 

int main() 
{ 
    // Initializing vector with array values 
    int arr[] = {10, 20, 5, 23 ,42 , 15}; 
    int n = sizeof(arr)/sizeof(arr[0]); 
    vector<int> vect(arr, arr+n); 

    cout << "Vector is: "; 
    for (int i=0; i<n; i++) 
        cout << vect[i] << " "; 

    cout << "\nMinimum element of vector is: "; 
    cout << *min_element(vect.begin(), vect.end()); 

    return 0; 
}

Smart Pointers

智能指针在C/C++的重要性

Pointers are used for accessing the resources which are external to the program like heap memory. So for accessing the heap memory if anything is created inside heap memory Pointers are used.

普通指针的缺陷

#include <iostream> 
using namespace std; 

class Rectangle { 
private: 
    int length; 
    int breadth; 
}; 

void fun() 
{ 
    // By taking a pointer p and 
    // dynamically creating object 
    // of class rectangle 
    Rectangle* p = new Rectangle(); 
} 

int main() 
{ 
    // Infinite Loop 
    while (1) { 
        fun(); 
    } 
}

在这里p是局部变量,因此将不再可能释放以前p所指向的空间,在无限循环中,最终会因为内存的严重泄漏而导致程序崩溃。

智能指针

当object在跳出其作用域之后,会自动调用其析构函数,由析构函数自动的完成资源的释放。一个简单的实现方式如下

#include <iostream> 
using namespace std; 

class SmartPtr { 
    int* ptr; // Actual pointer 
public: 
    // Constructor: Refer https:// www.geeksforgeeks.org/g-fact-93/ 
    // for use of explicit keyword 
    explicit SmartPtr(int* p = NULL) { ptr = p; } 

    // Destructor 
    ~SmartPtr() { delete (ptr); } 

    // Overloading dereferencing operator 
    int& operator*() { return *ptr; } 
}; 

int main() 
{ 
    SmartPtr ptr(new int()); 
    *ptr = 20; 
    cout << *ptr; 

    // We don't need to call delete ptr: when the object 
    // ptr goes out of scope, the destructor for it is automatically 
    // called and destructor does delete ptr. 

    return 0; 
}

下面是也给针对所有类型的简单实现

#include <iostream> 
using namespace std; 

// A generic smart pointer class 
template <class T> 
class SmartPtr { 
    T* ptr; // Actual pointer 
public: 
    // Constructor 
    explicit SmartPtr(T* p = NULL) { ptr = p; } 

    // Destructor 
    ~SmartPtr() { delete (ptr); } 

    // Overloading dereferncing operator 
    T& operator*() { return *ptr; } 

    // Overloading arrow operator so that 
    // members of T can be accessed 
    // like a pointer (useful if T represents 
    // a class or struct or union type) 
    T* operator->() { return ptr; } 
}; 

int main() 
{ 
    SmartPtr<int> ptr(new int()); 
    *ptr = 20; 
    cout << *ptr; 
    return 0; 
}

unique_ptr

If you are using a unique pointer then if one object is created and pointer P1 is pointing to this one them only one pointer can point this one at one time. So we can’t share with another pointer, but we can transfer the control to P2 by removing P1.

#include <iostream> 
using namespace std; 
#include <memory> 

class Rectangle { 
    int length; 
    int breadth; 

public: 
    Rectangle(int l, int b) 
    { 
        length = l; 
        breadth = b; 
    } 

    int area() 
    { 
        return length * breadth; 
    } 
}; 

int main() 
{ 

    unique_ptr<Rectangle> P1(new Rectangle(10, 5)); 
    cout << P1->area() << endl; // This'll print 50 

    // unique_ptr<Rectangle> P2(P1); 

    unique_ptr<Rectangle> P2; 
    P2 = move(P1); 

    // This'll print 50 
    cout << P2->area() << endl; 

    // cout<<P1->area()<<endl; 
    return 0; 
}

shared_ptr

If you are using shared_ptr then more than one pointer can point to this one object at a time and it’ll maintain a Reference Counter using use_count() method.

#include <iostream> 
using namespace std; 
#include <memory> 

class Rectangle { 
    int length; 
    int breadth; 

public: 
    Rectangle(int l, int b) 
    { 
        length = l; 
        breadth = b; 
    } 

    int area() 
    { 
        return length * breadth; 
    } 
}; 

int main() 
{ 

    shared_ptr<Rectangle> P1(new Rectangle(10, 5)); 
    // This'll print 50 
    cout << P1->area() << endl; 

    shared_ptr<Rectangle> P2; 
    P2 = P1; 

    // This'll print 50 
    cout << P2->area() << endl; 

    // This'll now not give an error, 
    cout << P1->area() << endl; 

    // This'll also print 50 now 
    // This'll print 2 as Reference Counter is 2 
    cout << P1.use_count() << endl; 
    return 0; 
}

weak_ptr

It’s much more similar to shared_ptr except it’ll not maintain a Reference Counter.In this case, a pointer will not have a strong hold on the object. The reason is if suppose pointers are holding the object and requesting for other objects then they may form a Deadlock.

Others

std::bitset

header
template class bitset;

Member Functions

operator[] Access Bits
count Count bits set
size Return size
test Return bit value
any Test if any bit is set
none Test if no bit is set
all Test if all bits are set
set Set bits
reset Reset bits
flip Flip bits
to_string Convert to string
to_ulong Convert to unsigned long integer
to_ullong Convert to unsigned long long
// bitset::operator[]
#include <iostream>       // std::cout
#include <bitset>         // std::bitset

int main ()
{
  std::bitset<4> foo;

  foo[1]=1;             // 0010
  foo[2]=foo[1];        // 0110

  std::cout << "foo: " << foo << '\n';

  return 0;
}

rand

int rand(void)
header

Returns a pseudo-random integral number in the range between 0 and RAND_MAX.

v1 = rand() % 100; // v1 in the range 0 to 99
v2 = rand() % 100 + 1; // v2 in the range 1 to 100
v3 = rand() % 30 + 1985; // v3 in the range 1985-2014

/* rand example: guess the number */
#include <stdio.h>      /* printf, scanf, puts, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */

int main ()
{
  int iSecret, iGuess;

  /* initialize random seed: */
  srand (time(NULL));

  /* generate secret number between 1 and 10: */
  iSecret = rand() % 10 + 1;

  do {
    printf ("Guess the number (1 to 10): ");
    scanf ("%d",&iGuess);
    if (iSecret<iGuess) puts ("The secret number is lower");
    else if (iSecret>iGuess) puts ("The secret number is higher");
  } while (iSecret!=iGuess);

  puts ("Congratulations!");
  return 0;
}

/*
    Guess the number (1 to 10): 5
    The secret number is higher
    Guess the number (1 to 10): 8
    The secret number is lower
    Guess the number (1 to 10): 7
    Congratulations!
*/

std::uniform_int_distribution

header
Produces random integer values i, uniformly distributed on the closed interval [a, b], that is, distributed according to the discrete probability function
C   STL - 图1
std::uniform_int_distribution satisfies all requirements of RandomNumberDistribution

#include <random>
#include <iostream>

int main()
{
    std::random_device rd;  //Will be used to obtain a seed for the random number engine
    std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
    std::uniform_int_distribution<> distrib(1, 6);

    for (int n=0; n<10; ++n)
        //Use `distrib` to transform the random unsigned int generated by gen into an int in [1, 6]
        std::cout << distrib(gen) << ' ';
    std::cout << '\n';
}

// 1 1 6 5 2 2 5 5 6 2


参考资料

https://www.geeksforgeeks.org/auto_ptr-unique_ptr-shared_ptr-weak_ptr-2/
_