C++ STL commonly used in algorithm competitions

1. Stack (stack)

The stack implements a first-in-last-out data structure, and the stack header file needs to be included when using it.

C++ defines stack syntax:

stack<int> s;//int为栈的数据类型,可以为string,double等

The basic operations of stack in C++ are:

1. Pop the stack: such as s.pop(), pay attention not to return the popped element
2. Push the stack: such as s.push(x)
3. Access the top element of the stack: such as s.top();
4. Determine the stack empty : For example, s.empty() returns true when the stack is empty
5. Returns the number of elements in the stack, such as: s.size()

Here is a simple example:

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

int main()
{
    std::stack<int> s;      //定义一个int类型的stack
    for(int i=0;i<10;i++)   //将数字0~9依次入栈
        s.push(i);

    std::cout << s.empty() << std::endl; //将输出0,表示栈不为空

    for(int i=0;i<10;i++)
    {
        std::cout << s.top() << std::endl;//输出栈顶的元素,依次为9、8、...、0
        s.pop();    //出栈
    }
    std::cout << s.empty() << std::endl;//将输出1,表示栈为空
    return 0;
}

Let's look at two algorithm problems applied to stacks:

Example one:

Topic description:
Suppose you want to compile a program that satisfies the following requirements: an expression contains only two kinds of parentheses: parentheses and square brackets, the order of nesting is arbitrary, and it is required to judge whether the parentheses of the expression match.
Input:
Multiple sets of input, each line input a set of strings consisting of parentheses.
Output:
For each set of test cases, output YES if matched, otherwise output NO
Example input:
[()([])]
()]
sample output:
YES
NO

Idea: Start from the first character of the string, push the parenthesis onto the stack when encountering a closing parenthesis, and check whether the top element of the stack matches when encountering an opening parenthesis (such as ')' matches '(', ')' matches '[' does not match), if it matches, pop the top element of the stack, if it does not match, output "NO" to end the example. Finally, it is necessary to judge whether the stack is empty. If it is empty, output "YES", otherwise output "NO".
Answer:
#include <iostream>
#include <string>
#include <stack>
using namespace std;
int main()
{
    /*freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);*/

    std::string str;
    std::stack<char> s;
    bool isMate;

    while(std::cin >> str)
    {
        isMate = true;
        for(int i = 0;i < str.size();i++)
        {
            if(str[i]=='('||str[i]=='[')
                s.push(str[i]);
            else if(str[i]==')')
            {
                if(!s.empty())
                {
                    if(s.top()!='(')
                    {
                        isMate = false;
                        std::cout << "NO" << std::endl;
                        break;
                    }
                    else
                        s.pop();
                }
                else
                {
                    isMate = false;
                    std::cout << "NO" << std::endl;
                    break;
                }
            }
            else if(str[i]==']')
            {
                if(!s.empty())
                {
                    if(s.top()!='[')
                    {
                        isMate = false;
                        std::cout << "NO" << std::endl;
                        break;
                    }
                    else
                        s.pop();
                }
                else
                {
                    isMate = false;
                    std::cout << "NO" << std::endl;
                    break;
                }
            }

        }
        if(isMate)
        {
            if(s.empty())
                std::cout << "YES" << std::endl;
            else
                std::cout << "NO" << std::endl;
        }

        while(!s.empty())
            s.pop();
    }
    return 0;
}
Example two:

Infix expression to postfix expression
Time limit : 3000 ms | Memory limit: 65535 KB
Source: http://acm.nyist.net/JudgeOnline/problem.php?pid=467 It is written in infix form, but it is more "accustomed" to suffix form for machines. The discussion on infix form and postfix form of arithmetic expressions has related content for reference. I won't go into details here. Now Your task is to convert infix to postfix. Input Input an integer n in the first line, there are n groups of test data (n<10). Each set of test data has only one line, which is a character string with a length of no more than 1000, which represents the infix expression of this expression, and each expression ends with "=". This expression contains only the symbols +-*/ and parentheses. The parentheses can be nested. The data guarantees that no negative numbers will appear in the input operands. The data guarantees that the divisor will not be output by 0. Each group outputs the corresponding suffix expression of the infix type of the group, and requires adjacent operand operators to be separated by spaces. Sample input 2 1.000+2/4= ((1+2)*5+1)/4= Sample output 1.000 2 4 / + = 1 2 + 5 * 1 + 4 / =














Ideas: http://blog.csdn.net/sgbfblog/article/details/8001651

Answer:

#include<iostream>
#include<stack>
#include<string>
using namespace std;

int main()
{
    /*freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);*/

    string str; //str为输入的中缀表达式
    string exp; //exp存储输出的后缀表达式
    stack<char> s;
    char ch;
    int t;
    cin >> t;
    while (t--)
    {
        cin >> str;
        str.insert(str.length(), "#");  //在中缀表达式加一个#字符作为结束标记
        for (int i = 0; i < str.length(); i++)
        {
            ch = str[i];
            if (ch >= '0'&&ch <= '9' || ch == '.')  //如果为数字则直接输出
            {
                if (str[i + 1] >= '0'&&str[i + 1] <= '9'||str[i + 1] == '.')//用来判断是不是个位数
                    exp += ch;
                else
                {
                    exp += ch;
                    exp += ' ';
                }
            }
            else if (ch == '+' || ch == '-')
            {
                while (!s.empty()&&s.top()!='(')    //弹出栈中元素直到遇到左括号或栈为空为止
                {
                    exp += s.top();     //取栈顶元素并存储在字符串exp中
                    exp += ' ';
                    s.pop();    //栈顶元素弹出
                }           
                s.push(ch);     //将当前操作符压入栈
            }
            else if (ch == '*' || ch == '/')
            {
                while (!s.empty() && s.top() != '+'&&s.top() != '-'&&s.top()!='(') //弹出栈中元素直到遇到加号、减号或者左括号为止
                {
                    exp += s.top(); //取栈顶元素并存储在字符串exp中
                    exp += ' ';
                    s.pop();    //栈顶元素弹出
                }
                s.push(ch);     //将当前操作符压入栈
            }
            else if (ch == '(') //遇到左括号直接压入栈但不输出
                s.push(ch);
            else if (ch == ')') //遇到右括号则弹出栈中元素直到遇到左括号为止
            {
                while (s.top() != '(')
                {
                    exp += s.top();
                    exp += ' ';
                    s.pop();
                }
                s.pop();   //弹出左括号
            }
            else if (ch == '#') //遇到结束符则弹出栈中所有元素
            {
                while (!s.empty())
                {
                    exp += s.top();
                    exp += ' ';
                    s.pop();
                }
            }
        }
        cout << exp << "=" << endl;
        exp = "";   //清空字符串
    }
    return 0;
}

2. Dynamic array (vector)

A vector in C++ is an array whose size can be changed. When solving a problem, you can't know the size of the array you need. You can use a vector to save space. Need to include the vector header file when using it.

The syntax for defining a one-dimensional dynamic array is

vector<int> a;  //int为该动态数组的元素数据类型,可以为string、double等

The syntax for defining a two-dimensional dynamic array is

vector<int*> a; //三维数据类型为int**,以此类推。

The basic operations of vector in C++ are:

1. push_back(x) adds element x at the end of the array.
2. pop_back() deletes the last element, no return value.
3. at(i) returns the element at position i.
4. begin() returns an iterator pointing to the first element.
5. end() returns an iterator pointing to the next position of the last element.
6. front() returns a reference to the array head.
7. capacity(x) allocates space for the vector
8, size() returns the size of the array
9, resize(x) changes the size of the array, if x is larger than the previously allocated space, the default value is automatically filled.
10. insert Insert element
① a.insert(a.begin(), 10); Insert 10 before the starting position of a.
②a.insert(a.begin(),3,10) Insert 10 into the array position 0-2.
11. Erase delete element
① a.erase(a.begin()); Delete the element at the starting position.
②a.erase(a.begin(),begin()+2); Delete the elements between 0 and 2.
12. rbegin() returns an iterator in reverse order, which points to the last element.
13. render() returns a reverse iterator pointing to the position before the first element.
14. clear() clears all elements.

Here is a simple example:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main()
{
    vector<int> a;
    vector<int> b;

    for (int i = 0; i < 10; i++)    //向数组a依次添加0~9
        a.push_back(i);

    a.swap(b);      //将数组a元素与数组b元素交换
    cout << a.size() << " " << b.size() << endl;    //此时应当输出 0 10

    for (vector<int>::iterator it = b.begin(); it != b.end(); it++)//从第一个元素开始遍历数组元素
        cout << *it << " ";     //依次输出0~9
    cout << endl;

    b.erase(b.begin() + 1);     //删除位置1的元素,即元素1.
    cout << b.size() << endl;   //由于删除了一个元素,此时输出应当为8

    for (vector<int>::reverse_iterator rit = b.rbegin(); rit != b.rend(); ++rit)//逆向输出数组元素
        cout << *rit << " ";    //应当输出9 8 7 6 5 4 3 2 0
    cout << endl;

    b.resize(9);    //将数组空间设定为9,相当于比之前多了1个位置
    b.push_back(20);//在尾部添加元素20

    for (vector<int>::iterator it = b.begin(); it != b.end(); it++)
        cout << *it << " ";  //应当输出0 2 3 4 5 6 7 8 9 20

    return 0;
}

The following is an example problem applied to the vector:

Title: Where is the Marble? (Uva 10474)

Link: https://vjudge.net/problem/UVA-10474
Brief translation: Example question:
Where are the marbles
There are N marbles, and a non-negative integer is written on each marble, first sort the numbers from small to large,
and then answer Q question. Each
question which marble has an x ​​written on it. The sorted marbles are numbered 1~N from left to right. (In the example, to
save space, all marble numbers are combined on one line, and all questions are combined on one line.) Input ends with 0 0

Sample input:
4 1
2 3 5 1
5
5 2
1 3 3 3 1
2 3
0 0
Sample output:
CASE# 1:
5 found at 4
CASE# 2:
2 not found
3 found at 3

Idea: first sort the marble numbers from small to large, then start from the first question, traverse the marbles, if found, output the array subscript +1 of the marble, if not found, output not found, and then start from the second question , and so on.

Answer:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main()
{
    /*freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);*/

    vector<int> a;  //定义一个动态数组a,用来存储大理石编号
    vector<int> find;   //定义动态数组find,存储待查找的大理石编号
    int N, Q;
    int tmp, count = 0;
    bool flag;
    while (cin >> N >> Q)
    {
        if (N == 0 && Q == 0)
            break;
        for (int i = 0; i < N; i++)
        {
            cin >> tmp;
            a.push_back(tmp); //依次输入大理石编号
        }
        for (int i = 0; i < Q; i++)
        {
            cin >> tmp;   
            find.push_back(tmp);//依次输入待查找编号
        }

        sort(a.begin(), a.end());   //对数组a进行从大到小排序
        flag = false;               //标记是否找到
        cout << "CASE# " << ++count << ":" << endl;
        for (int i = 0; i < Q; i++) //从第一个问题开始
        {
            flag = false;
            for (int j = 0; j < N; j++)
                if (find.at(i) == a.at(j)) //如果找到
                {
                    cout << find.at(i) << " found at " << j + 1 << endl;
                    flag = true;
                    break;
                }
            if (!flag) //没有找到
                cout << find.at(i) << " not found" << endl;
        }
        a.clear();  //清空数组,为下一组数据准备
        find.clear();
    }
    return 0;
}

3. Set (set)

Sets in C++ are similar to mathematical sets, that is, each element can only appear once, and the set header file needs to be included to use this container.

The syntax for defining a set is:

set<int> s; //int为集合的数据类型,可以为string,double等

The basic operations of set in C++ are:

1. begin() returns an iterator pointing to the first element.
2. end() returns an iterator pointing to the next position of the last element.
3. clear() clears all elements of the set.
4, empty () to determine whether it is empty.
5. size() returns the current number
of elements 6. erase(it) deletes the element pointed to by the iterator pointer it.
7, insert (a) insert element a
8, count () to find the number of times an element appears, only possible 0 or 1.
9. find() finds the position where an element appears, if found, it returns the iterator of this element, if it does not exist, it returns s.end()

Here is a simple example:

#include <iostream>
#include <algorithm>
#include <set>
using namespace std;

int main()
{
    set<int> s;
    s.insert(20);
    s.insert(10);
    s.insert(30);
    s.insert(10);

    cout << s.size() << endl; //将输出3,因为集合中元素不能重复
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
        cout << *it << " ";     //将输出10 20 30,集合会自动排序
    cout << endl;

    //将输出1 0
    cout << count(s.begin(), s.end(), 20) << " " << count(s.begin(), s.end(), 40) << endl;

    s.erase(s.find(10));    //删除元素10
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
        cout << *it << " "; //将输出20 30
    return 0;
}

Here are some examples of applying sets:

Title: Andy's First Dictionary

Link: https://vjudge.net/problem/UVA-10815
Title description: Read an English article, including various punctuation marks, and ask to output all the different words in the article in lexicographical order.
Sample input:
Adventures in Disneyland
Two blondes were going to Disneyland when they came to a fork in the
road. The sign read: “Disneyland Left.”
So they went home.
Sample output:
a
adventures
blondes
came
disneyland
fork
going
home
in
left
read
road
sign
so
the
they
to
two
went
were
when the
answer:

Ideas: Start traversing from the first character of the article, directly change to lowercase letters when encountering uppercase letters, and replace them with spaces when encountering punctuation marks. It is then stored in a collection through a string stream, and finally the element of the collection is printed as the answer.

#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <sstream>
using namespace std;

int main()
{
    set<string> s; //定义一个集合s,用来存储单词
    string str, tmp;
    while (cin >> str) //读入一个单词(可能包含标点符号)
    {
        for (string::iterator it = str.begin(); it != str.end(); it++) //遍历该单词元素
        {
            if (isalpha(*it))  //判断是否是英文字母
                *it = tolower(*it); //转换为小写
            else
                *it = ' ';  //如果是标点符号则用空格替代它
        }
        stringstream sstr(str);  //定义一个字符串流并将处理后的单词赋值给它
        while (sstr >> tmp)   //将该流输入到字符串tmp中,因为可能包含空格所以需要使用循环
            s.insert(tmp);    //插入到集合s中,若集合中已经存在该单词则不会插入
    }
    for (set<string>::iterator it = s.begin(); it != s.end(); it++)
        cout << *it << endl;
    return 0;
}

Fourth, the queue (queue)

Queue implements a first-in, first-out data structure, and needs to include the queue header file when using it.

The syntax for defining a queue is:

queue<int> q;   //int为队列的数据类型,可以为string,double等

The basic operations of queue in C++ are:

1. Entering the queue, such as: q.push(x) puts the element x at the end of the queue
2. Dequeuing, such as: q.pop() also does not return the value of the popped element
3. Returns the first element of the queue, such as: q.front();
4. Return the elements at the end of the queue, such as: q.back();
5. Determine whether it is empty, such as: q.empty();
6. Return the number of queue elements, such as: q.size( );

Here is a simple example:

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

int main()
{
    queue<int> q;
    for(int i = 0;i < 10;i++)   //将0~9依次入队
        q.push(i);

    cout << q.front() << " " << q.back() << endl; //这里应当输出0和9

    //依次输出0、1、...、9
    for(int i = 0;i < 10;i++)
    {
        cout << q.front() << " ";
        q.pop();
    }
    return 0;
}

Summarize:

By learning common C++ templates, the probability of code errors and the difficulty of debugging can be effectively reduced in the actual process of writing questions, the thinking is clearer, the code is more concise and clear, and the speed and accuracy of writing questions can be effectively improved.
If this blog is wrong, please correct me.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326125759&siteId=291194637