简单排序 去重 掌握了几个STL容器

本文探讨了使用C++标准库中的vector和set进行数据去重和排序的方法,包括利用unique函数去除vector中重复元素,以及通过set自动进行排序和去重的过程。同时,还介绍了如何使用map来存储和输出键值对。

http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2378

 

vector   先排序 再去重unique

#include <iostream>
#include <cstdio>
#include <set>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <functional>
#include <algorithm>

using namespace std;


bool judge(char ch) {
    if (ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch == '-' || ch == '_')
        return true;
    return false;
}
vector<string> v;
bool cmp(const string a, const string b) {
    return a < b;
}
int main() {

    int t;
    scanf("%d", &t);
    getchar();
    while (t--) {
        v.clear();
        //ans.clear();
        int n;
        scanf("%d", &n);
        getchar();
        while (n--) {
            char str[150];
            gets(str);
            //printf("%s\n", str);
            int len = strlen(str);
            //printf("%d", len);
            for (int i = 0; i < len ; ++i) {
                //如果有后一位    如果是首  是@且后是合法     或者   前不合法中@后合法
                if (i + 1 < len && (!i && str[i] == '@' && judge(str[i + 1]) || str[i] == '@' && !judge(str[i - 1]) && judge(str[i + 1]))) {
                    string in = "";
                    in += str[i + 1];
                    for (int j = i + 2; j < len; ++j) {
                        if (judge(str[j])) {
                            in += str[j];
                        }
                        else
                            break;
                    }
                    //ans.insert(in);
                    v.push_back(in);
                }
            }

        }
        sort(v.begin(), v.end(), cmp);
        v.erase(unique(v.begin(), v.end()), v.end());
        printf("%d\n", v.size());
        for (auto it = v.begin(); it != v.end(); ++it) {
           cout << *it << endl;
        }
    }
    return 0;
}

map的自动排序  怎么输出key值

#include <iostream>
#include <cstdio>
#include <set>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <functional>

using namespace std;


bool judge(char ch) {
    if (ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch == '-' || ch == '_')
        return true;
    return false;
}
map<string, int> ma;
int main() {

    int t;
    scanf("%d", &t);
    getchar();
    while (t--) {
        ma.clear();
        //ans.clear();
        int n;
        scanf("%d", &n);
        getchar();
        while (n--) {
            char str[150];
            gets(str);
            //printf("%s\n", str);
            int len = strlen(str);
            //printf("%d", len);
            for (int i = 0; i < len ; ++i) {
                //如果有后一位    如果是首  是@且后是合法     或者   前不合法中@后合法
                if (i + 1 < len && (!i && str[i] == '@' && judge(str[i + 1]) || str[i] == '@' && !judge(str[i - 1]) && judge(str[i + 1]))) {
                    string in = "";
                    in += str[i + 1];
                    for (int j = i + 2; j < len; ++j) {
                        if (judge(str[j])) {
                            in += str[j];
                        }
                        else
                            break;
                    }
                    //ans.insert(in);
                    ma[in] = 1;
                }
            }

        }
        printf("%d\n", ma.size());
        for (auto it = ma.begin(); it != ma.end(); ++it) {
           cout << it->first << endl;
        }
    }
    return 0;
}

 

set的去重 和排序

#include <iostream>
#include <cstdio>
#include <set>
#include <string>
#include <cstring>

using namespace std;

set<string> ans;

bool judge(char ch) {
    if (ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch == '-' || ch == '_')
        return true;
    return false;
}
int main() {

    int t;
    scanf("%d", &t);
    getchar();
    while (t--) {
        ans.clear();
        int n;
        scanf("%d", &n);
        getchar();
        while (n--) {
            char str[150];
            gets(str);
            //printf("%s\n", str);
            int len = strlen(str);
            //printf("%d", len);
            for (int i = 0; i < len ; ++i) {
                //如果有后一位    如果是首  是@且后是合法     或者   前不合法中@后合法
                if (i + 1 < len && (!i && str[i] == '@' && judge(str[i + 1]) || str[i] == '@' && !judge(str[i - 1]) && judge(str[i + 1]))) {
                    string in = "";
                    in += str[i + 1];
                    for (int j = i + 2; j < len; ++j) {
                        if (judge(str[j])) {
                            in += str[j];
                        }
                        else
                            break;
                    }
                    ans.insert(in);
                }
            }

        }
        printf("%d\n", ans.size());
        for (auto it = ans.begin(); it != ans.end(); ++it) {
           cout << *it << endl;
        }
    }
    return 0;
}

 

<think>好的,我需要回答用户关于在C++中实现排序的方法的问题。首先,我应该回忆一下C++中常用的数据结构和算法。记得set和multiset容器可以自动排序,并且set还能。用户提供的引用中提到了使用set的构造和迭代器遍历,这可能是一个关键点。 接下来,我需要考虑数组或向量的情况。如果用户有一个已有的数组需要处理,可能需要先排序,然后。引用3提到了数组的方法,使用双指针法,这可能是一个有效的方法。比如,排序后遍历数组,将不复的元素移到前面,然后调整数组大小。 然后,用户可能需要不同的方法,比如使用STL中的算法。例如,使用std::sort进行排序,再结合std::unique和erase方法复元素。这种方法适用于vector,因为unique将复元素移到末尾,返回新的逻辑结尾,之后可以erase掉多余的元素。 另外,需要比较不同方法的优缺点。比如,使用set的方法简单,但可能效率较低,因为插入操作的时间复杂度是O(n log n),而先排序可能更高效,特别是对于已经排序的数据。同时,要考虑是否需要保持原有顺序,但通常排序会改变顺序。 还要注意用户提供的代码示例中的问题,比如数组越界,引用3中的解决方法是通过遍历和双指针来避免。这可能是一个常见的错误点,需要在回答中提醒用户注意。 最后,应该总结几种常见的方法,并给出代码示例,如使用set、使用vector结合sort和unique,以及手动的双指针法。同时,引用提供的参考资料来支持回答,确保正确性。 现在需要组织这些思路,分步骤解释每种方法,确保结构清晰,代码正确,并符合用户要求的格式,比如行内数学表达式用$...$,独立公式用$$...$$。不过在这个问题中可能数学公式不多,但需要注意LaTeX的正确使用。例如,时间复杂度可以表示为$O(n \log n)$。 可能还需要生成相关问题,比如不同方法的效率比较,如何处理自定义类型的排序,或者在时保留某些条件等。根据用户提供的示例,相关问题应该围绕实现方法、优化和应用场景展开。 总之,回答需要涵盖多种实现方式,提供代码示例,引用相关资料,并附上相关问题,确保用户能够全面理解C++中排序的实现方法。</think>在C++中实现排序功能主要有以下三种典型方法,分别适用于不同场景: ### 一、利用`set`容器实现自动排序 `set`容器基于红黑树实现,具有以下特性: 1. 元素自动按升序排列 2. 自动过滤复元素 3. 插入时间复杂度为$O(\log n)$ ```cpp #include <set> #include <vector> std::vector<int> processWithSet(const std::vector<int>& arr) { std::set<int> sorted_set(arr.begin(), arr.end()); return std::vector<int>(sorted_set.begin(), sorted_set.end()); } ``` 该方法会丢失原数组顺序,但能保证最终结果有序且唯一[^1] ### 二、使用`sort`+`unique`组合(适用于vector) 1. 先排序的经典组合 2. 时间复杂度主要取决于排序的$O(n \log n)$ ```cpp #include <algorithm> #include <vector> void sortAndUnique(std::vector<int>& vec) { // 排序 std::sort(vec.begin(), vec.end()); // (返回新逻辑终点) auto last = std::unique(vec.begin(), vec.end()); // 删除复元素 vec.erase(last, vec.end()); } ``` 该方法会修改原始数组,但内存利用率更高[^2] ### 三、手动实现双指针(适用于已排序数组) 适用于需要控制内存操作或特殊逻辑的场景: ```cpp void manualUnique(std::vector<int>& vec) { if(vec.empty()) return; int write_index = 1; for(int read_index = 1; read_index < vec.size(); ++read_index) { if(vec[read_index] != vec[write_index-1]) { vec[write_index++] = vec[read_index]; } } vec.resize(write_index); } ``` 此方法要求输入数组已排序,时间复杂度为$O(n)$[^3] ### 性能对比 | 方法 | 时间复杂度 | 空间复杂度 | 保持原序 | |-----------|---------|-------|------| | set | O(n logn)| O(n) | ❌ | | sort+unique| O(n logn)| O(1) | ❌ | | 手动双指针 | O(n) | O(1) | ✅ | ### 扩展应用 1. **自定义类型处理**:需载`operator<`或提供比较函数 2. **稳定**:使用`stable_sort`保持相同元素的相对顺序 3. **条件**:在`unique`前自定义相等判断条件
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值