从数组中删除元素的算法

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

算法的目标是删除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;
}
相关推荐
To_OC3 小时前
LC 1 两数之和:面试第一道必考题,暴力解法直接被面试官 pass
javascript·算法·leetcode
鱼鱼不愚与8 小时前
《原来如此 | 第01期:为什么导航软件能预测红绿灯倒计时?》
算法
博客180011 小时前
酷宝的使用方法,超好用的免费界面库,C++、MFC可用
c++·mfc·界面库·库来帮·酷宝
郝学胜_神的一滴13 小时前
CMake 026:属性体系精讲、四大作用域全解 & 实战代码落地
c++·cmake
复杂网络13 小时前
论最小 Agent 计算机的形态
算法
kisshyshy1 天前
🍦 雪糕、食堂、火车厢:三幅漫画吃透栈、队列与链表
javascript·算法
众少成多积小致巨1 天前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++
猿人谷1 天前
不只是 CPU 阈值:STAR 如何用 GAT + Transformer 做容器级自动扩缩容?
人工智能·算法
复杂网络2 天前
Stable Diffusion 视觉大模型微调技术深度调研
算法