从数组中删除元素的算法

以下代码中,s是待删除元素的数组.v_deleted以s德索引为索引,指出s中索引对应的元素是否需要删除.即若v_deleted[i]=true,则s[i]需要删除,否则应当保留

算法的目标是删除s中所有被v_deleted标记的元素,同时返回一个数组,数组索引为i的元素指出被删除元素后的s索引为i的元素在删除前的s中的索引.

该算法有两种不同的实现,分别由delete_in_list和delete_in_list2两个函数给出

两种算法的最明显的不同之处在于,delete_in_list先将s拷贝到链表assist_space,在assist_space上删除,再把assist_space拷贝回s,而delete_in_list2直接在s上执行删除,这样当s非常大或要删除的元素很多且T的析构开销非常大时, delete_in_list的效率会比delete_in_list2更高

C++代码:

cpp 复制代码
#include <iostream>
#include <vector>
#include <list>

using std::vector;
using std::list;

template<typename T>
vector<size_t> delete_in_list(vector<T>& s, const vector<int>& v_deleted)  //从left中删除被标记被删除的顶点,返回旧顶点索引和新索引映射关系的数组
{
    vector<size_t> assist_v(s.size());
    for (size_t k = 0; k < assist_v.size(); ++k)
    {
        assist_v[k] = k;
    }
    list<T> assist_space;
    assist_space.insert(assist_space.end(), s.begin(), s.end());
    bool find_new_delete_start = false;
    size_t new_delete_start_index = 0;
    size_t new_delete_start_for_assist = 0;
    typename list<T>::iterator it = assist_space.begin();
    size_t k = 0;
    for (; k < s.size(); ++k)
    {
        if (v_deleted[k] == 1)
        {
            if (find_new_delete_start == false)
            {
                find_new_delete_start = true;
                new_delete_start_index = k;
            }
        }
        else
        {
            if (find_new_delete_start)
            {
                auto d_r = assist_v.erase(assist_v.begin() + new_delete_start_for_assist, assist_v.begin() + (new_delete_start_for_assist + k - new_delete_start_index));
                auto run_it = it;
                for (size_t m = 0; m < k - new_delete_start_index; ++m)
                {
                    ++run_it;
                }
                it = assist_space.erase(it, run_it);

                find_new_delete_start = false;
                new_delete_start_for_assist = d_r - assist_v.begin();
            }
            ++new_delete_start_for_assist;
            ++it;
        }
    }

    if (find_new_delete_start)
    {
        assist_v.erase(assist_v.begin() + new_delete_start_for_assist, assist_v.end());
        assist_space.erase(it, assist_space.end());
    }

    //size_t v_num_before_delete = left.size();
    s.clear();
    s.insert(s.end(), assist_space.begin(), assist_space.end());
    /*vector<size_t> index_after_delete_to_original(v_num_before_delete);
    for (size_t m = 0; m < assist_v.size(); ++m)
    {
        index_after_delete_to_original[assist_v[m]] = m;
    }*/
    return assist_v;
}

template<typename T>
vector<size_t> delete_in_list2(vector<T>& s, const vector<int>& v_deleted)
{
    typename vector<T>::iterator it = s.begin();
    vector<size_t> assist_v(s.size());

    for (size_t i = 0; i < assist_v.size(); ++i)
    {
        assist_v[i] = i;
    }

    vector<size_t>::iterator run_a = assist_v.begin();
    typename vector<T>::iterator delete_start;
    vector<size_t>::iterator delete_start_a;
    while (true)
    {
        while (it != s.end() && v_deleted[*run_a] == 0)
        {
            ++it;
            ++run_a;
        }

        if (it == s.end())
        {
            break;
        }

        delete_start = it;
        delete_start_a = run_a;
        do
        {
            ++it;
            ++run_a;
        } while (it != s.end() && v_deleted[*run_a] == 1);

        it = s.erase(delete_start, it);
        run_a = assist_v.erase(delete_start_a, run_a);

        if (it == s.end())
        {
            break;
        }
    }
    return assist_v;
}  //当s非常大或要删除的元素很多且T的析构开销非常大时, delete_in_list的效率会比delete_in_list2更高

template<typename T>
void subset(vector<int>& v_deleted, size_t index, const vector<T>& s)
{
    if (index == s.size())
    {
        vector<T> t1 = s;
        vector<size_t> r1 = delete_in_list2(t1, v_deleted);
        vector<T> t2 = s;
        vector<size_t> r2 = delete_in_list(t2, v_deleted);
        if (t1 != t2 || r1 != r2)
        {
            std::cout << "error" << std::endl;
            exit(-1);
        }
        return;
    }

    v_deleted[index] = 0;
    subset(v_deleted, index + 1, s);
    v_deleted[index] = 1;
    subset(v_deleted, index + 1, s);
}
int main()
{
    const int N = 5;
    vector<int> s(N);
    for (int i = 0; i < N; ++i)
    {
        s[i] = i;
    }
    vector<int> v_deleted(N);
    subset(v_deleted, 0, s);
    return 0;
}
相关推荐
特种加菲猫44 分钟前
STL关联容器:Set/Multiset与Map/Multimap详解
开发语言·c++
Andy1 小时前
C++ list容器基本逻辑结构详解
c++·windows·list
斯内科2 小时前
四胞胎素数:找出‌个位数分别是 1、3、7、9‌,且‌十位及更高位数字完全相同‌的质数,例如 11、13、17、19
算法·质数·素数·四胞胎素数
Hello.Reader2 小时前
算法基础(十二)——主方法:快速求解常见递归式
算法
想唱rap2 小时前
传输层协议TCP
linux·运维·服务器·网络·c++·tcp/ip
小O的算法实验室2 小时前
2026年IEEE TITS,面向按需外卖配送调度的特定问题知识与基于学习元启发式算法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
加勒比海带663 小时前
目标检测算法——农林行业数据集汇总附下载链接【Plant】
大数据·图像处理·人工智能·算法·目标检测
洛水水3 小时前
【力扣100题】23. 螺旋矩阵
算法·leetcode·矩阵
瑶池酒剑仙3 小时前
C++类和对象完全指南:从封装继承多态到内存布局的面向对象宝典(雨夜论道)
c语言·开发语言·c++·visual studio