• 正则表达式regex+数组去重+两熊分蜂蜜【动态规划】


    正则表达式regex

    还是要跟着例子结合看

    例如:

    • runoo+b,可以匹配 runoob、runooob、runoooooob 等,+ 号代表前面的字符必须至少出现一次(1次或多次)。

    • runoo*b,可以匹配 runob、runoob、runoooooob 等,* 号代表前面的字符可以不出现,也可以出现一次或者多次(0次、或1次、或多次)。

    • colou?r 可以匹配 color 或者 colour? 问号代表前面的字符最多只可以出现一次(0次或1次)。 

     

    菜鸟:https://www.runoob.com/regexp/regexp-syntax.html 

     \D元字符可以匹配非数字字符,等价于"[^0-9]"。

    数组去重

    unique函数的去重过程实际上就是不停的把后面不重复的元素移到前面来,也可以说是用不重复的元素占领重复元素的位置。

    单纯的使用unique函数的话,容器的长度并没有发生变化,只是元素的位置发生了变化:【在使用前绝大数情况下需要对容器中的元素进行排序】

    vector<int> a = {1,3,3,4,5,6,6,7};
        vector<int>::iterator it_1 = a.begin();
        vector<int>::iterator it_2 = a.end();
    
        sort(it_1,it_2);
        cout<<"去重前的 a : ";
        for(int i = 0 ; i < a.size(); i++){
             cout<<a[i]<<" ";
        }cout<<endl;// 1 3 3 4 5 6 6 7
    
        unique(it_1,it_2);
    
        cout<<"去重后的 a : ";
        for(int i = 0 ; i < a.size(); i++){
             cout<<a[i]<<" ";
        }// 1 3 4 5 6 7 6 7(没3了)
    //unique去重的过程是将重复的元素移到容器的后面去:不正确,应该是把不重复的元素移到前面来。
    //和erase函数一起:new_end = unique(it_1,it_2);  a.erase(new_end,it_2);
    View Code
     int a[10] = { 0, 7, 7, 6, 1, 1, 5, 5, 8, 9 };
        int n = unique(a, a + 10) - a;
    //函数返回值不是去重后容器中元素的数量,而是去重后容器中的末地址。
    //也就是说,如果想得到去重后容器中元素的数量的话还要减去初始地址
        cout << n << endl;// 7:最后一个不重复数字的下标
        
        for (int i = 0; i < 10; i++){
            cout << a[i] << " ";  // 0 7 6 1 5 8 9 5 8 9
        }
        for (int i = 0; i < n; i++){
            cout << a[i] << " ";  // 0 7 6 1 5 8 9
        }
    View Code

    unique函数通常和erase函数一起使用,来达到删除重复元素的目的。(注:此处的删除是真正的删除,即从容器中去除重复的元素,容器的长度也发生了变换;

    #include<stdc++.h>
    using namespace std;
     
    int main()
    {
     
        vector<int> a ={1,3,3,4,5,6,6,7};
        vector<int>::iterator it_1 = a.begin();
        vector<int>::iterator it_2 = a.end();
        vector<int>::iterator new_end;
     
        new_end = unique(it_1,it_2); 
    //注意unique的返回值,去重后序列(这个序列不含有重复数值)的末尾的下一个元素
        a.erase(new_end,it_2);
        cout<<"删除重复元素后的 a : ";
        for(int i = 0 ; i < a.size(); i++)
            cout<<a[i];
        cout<<endl;
     
    }
    View Code

    erase()用法

    //1. string容器所特有  删除容器中从pos位置开始的n个元素
        string str = "hello world!"; cout<<str.erase(0,1)<<endl;
    
        //2. 删除容器中position所指位置的元素
        string str = "hello world!";
        string::iterator it_1 = str.begin();
        str.erase(it_1);
    
        //3. 删除容器中first到last之间的所有元素(左闭右开)
        string str = "hello world!";
        string::iterator it_1 = str.begin();
        string::iterator it_2 = str.begin() + 1;
        str.erase(it_1,it_2);
    //以上都能使hello变成ello
    View Code

     Vector去重

    vector<int> A;//vector:A.size();返回值是无符号整数 0-1会变大https://blog.csdn.net/h799710/article/details/109445906
    //取元素值时通过下标A[i]或迭代器时的指针*
        A.push_back(1);A.push_back(2);A.push_back(1);A.push_back(2);
        A.push_back(2);A.push_back(2);
    
        //删除重复数据
        for (vector<int>::iterator i = A.begin(); i != A.end() - 1; ++i) {
            for (vector<int>::iterator j = i + 1; j != A.end();++j) {
                cout<<*i<<"  "<<*i;
                if (*i == *j) {
                    j = A.erase(j);
                    --j;//!! 向量erase()的删除时,返回值指向删除元素的下一个 待会还有++j呢
                }
            }
        }
    
        //排序并删除重复
        void elimDups(vector<string> &words)
        {
    
            sort(words.begin(),words.end());
            auto end_unique = unique(words.begin(),words.end());
            words.erase(end_unique,words.end());
        }
    
        //删去指定的数值
        int val = 4 || 7;//伪代码
        vector<int>::iterator it;
        for(it=A.begin();it!=end();++it){
            if(*it == val){
                it = A.erase(it);
                --it;//!!
            }
        }
    
    
    
        for (int i = 0; i < A.size(); ++i)
            cout << A[i];
        cout << endl;
    View Code

     计算数组中可构成三角形的个数

    要想构成三角形,只需三角形中两条最短边之和大于最长边。

    双指针法:
    基于这样的原理,我们可以先将数组从小到大进行排序。将数组排序后,我们可以这样想,固定某一个数,然后用左右两个指针分别指向某个数,当左右指针指向的数字之和大于我们固定的数时,说明此种情况成立。然后将右指针向左移动一位继续判断直到不满足为止,将左指针向右移动一位继续判断;直到左指针跟右指针重合。

    根据这个思路,我们将数组从大到小遍历,将当前遍历的数nums[i]进行固定,让左指针指向第0个数nums[0],右指针指向这个数的左边一个数nums[i-1]。当nums[left]+nums[right]>nums[i]时,把右指针right固定,可以想到:当左指针left往右遍历时,左指针与右指针之间的和肯定也满足要求;因此有count+=(right-left)。【固定右指针 此时左指针到右中间这段都是满足条件的 所以直接count+=就行】
    将右指针right往左移一位,继续进行判断,如果成立,则right继续重复前面操作;如果不成立,说明两个数之和太小了,此时将左指针left往右移一位,继续进行判断,直到left与right指针重合,这样就把nums[i]所有的情况都考虑了,最后数组遍历完结果就出来了

    class Solution {
    public:
        int triangleNumber(vector<int>& nums) {
            int count = 0, size = nums.size();//由无符号转成int了 大胆-1
            sort(nums.begin(), nums.end());
            for (int i = size - 1; i >= 2; i--) {
                int left = 0, right = i - 1;
                while(left < right) {
                    if (nums[left] + nums[right] > nums[i]) {
                        count += (right - left);
                        right--;
                    }
                    else {
                        left++;
                    }
                }
            }
            return count;
        }
    };
    View Code

    深信服笔试的要求不输出重复三角形:

    1. 结构体xyz+bool:用malloc/new创建结构体数组,得到满足条件的所有三角形后,考虑删除:三条边全相等就不输出:将arr[i]三角形的三条边sort排序,之后A.x1==B.x1 && A.x2==B.x2 && A.x3==B.x3此种情况下相等再删除bool=false【不排序的话 2 3 4  3 2 4也是相同的哇】

    2.结构体sort unique erase

    //1. sort()改写     sort(first_pointer,first_pointer+n,cmp)默认升序
    struct Student {
        char name[11];
        int solve;
        int time;
    }p[10000];
    bool cmp(const Student& a, const Student& b)//常量引用
    {
        if (a.solve != b.solve)
         {
            if (a.solve > b.solve)
                return true;
            else
                return false;
        }
        else if (a.time != b.time)
               return a.time < b.time;
        else  return (strcmp(a.name, b.name) < 0);
    }
    sort(p,p+n,cmp);
    
    //重载小于号
    struct Student
    {
        string name;
        int MathGrade;
        int ChineseGrade;
        //重载小于号,语文成绩大的学生排在前面,结构体中的变量ChineseGrade
        bool operator< (const Student& tmp) const
        {
            return ChineseGrade > tmp.ChineseGrade;
        }
    };
    sort(students, students+5);
    View Code

    两熊分蜂蜜

    两熊分蜜吵架分家;

    要求:
    1. 尽可能的重量均分,至少自己能少的最少;
    2. 在罐子数量上差距不能超过1。
    输入描述:
    1. 每一行给出蜜罐的数量,2<= n <= 100
    2. 每蜜罐的重量 1< M <= 500
    输出描述:两个数字A B 分别表示熊大和熊二能分到蜜的总重
    输入:
    3
    447
    56
    249
    输出:305 447

    一组数 如何分类 使得差值最小

    动态规划--背包问题

  • 相关阅读:
    最挑战程序员的9大任务,你都干过哪些?
    最挑战程序员的9大任务,你都干过哪些?
    .NET版开源日志框架Log4Net详解
    .NET版开源日志框架Log4Net详解
    .NET版开源日志框架Log4Net详解
    IT人永远不老,老程序员价值何在?
    IT人永远不老,老程序员价值何在?
    IT人永远不老,老程序员价值何在?
    JS 对象封装的常用方式
    JS 对象封装的常用方式
  • 原文地址:https://www.cnblogs.com/yundong333/p/15996808.html
Copyright © 2020-2023  润新知