简体   繁体   English

如何从向量中删除随机元素而不重复它们并保留元素顺序? C ++

[英]how to remove random elements from a vector without repeating them and preserving element order? C++

I want to remove a determined amount of random elements from a vector while preserving element order. 我想从向量中删除确定数量的随机元素,同时保留元素顺序。 I wrote this code for that purpose and it works well when I run it for small vectors but when I run it for large ones (1000 total elements removing 200 random elements) it doesn't seem to work properly. 我为此目的编写了此代码,当我将其用于较小的矢量时,它运行得很好,但是当针对较大的矢量(总共1000个元素,除去200个随机元素)运行时,它似乎无法正常工作。

Could anyone give me a kick in the right direction? 谁能给我正确的方向踢?

#include<iostream>
#include<cmath>
#include<stdio.h>
#include<stdlib.h>
#include<fstream>
#include<string>
#include<iomanip>
#include<vector>
#include "mersenne.cpp"
#include "userintf.cpp"
#include "stocc.h"
#include "stoc1.cpp"
#include<time.h>
#include <algorithm>
#include "./Mersenne-1.1/MersenneTwister.h"



MTRand mtrand1;

using namespace std ;

int main() 
{
    vector<string> stable ;


    stable.push_back("CCAAAATCAACTCCTCGAGGAAGTAAATGCGATGGCTGTGTTACAGCGTGTATCGCGTCATGTCCTTGTTGCTGTAATTTCCACTGTCAGGACGATGAAAGCGCCGGGACGAAGGGCCATCAGGGGCTACTCCAGACCGACGAGTTCCCTCTCTGCCAGAAAATATGTTGTGGTGCGAGTTTTAACATACACTGCGGGACCAGCAAGCCG") ;
    stable.push_back("CCAAAATCAACTCCTCGAGGAAGTAAATGCGATGGCTGTGTTACAGCGTGTATCGCGTCATGTCCTTGTTGCTGTAATTTCCACTGTCAGGACGATGAAAGCGCCGGGACGAAGGGCCATCAGGGGCTACTCCAGACCGATGAGTTCCCTCTCTGCCAGAAAATATGTTGTGGTGCGAGTTTTAACATACACTGCGGGACCAGCAAGCCA") ;
    stable.push_back("CCAAAATCAACTCCTCGAGGAAGTAAATGCGATGGCTGTGTTACAGCGTGTATCGCGTCATGTCCTTGTTGCTGTAATTTCCACTGTCAGGACGATGAAAGCGCCGGGACGAAGGGCCATCAGGGGCTACTCCAGACCGACGAGTTCCCTCTCTGCCAGAAAATATGTTGTGGTGCGAGTTTTAACATACACTGCGGGACCAGCAAGCCA") ;
    stable.push_back("CCAAAATCAACTCCTCGAGGAAGTAAATGCGATGGCTGTGTTACAGCGTGTATCGCGTCATGTCCTTGTTGCTGTAATTTCCACTGTCAGGACGATGAAAGCGCCGGGACGAAGGGCCATCAGGGGCTACTCCAGACCGACGAGTTCCCTCTCTGCCAGAAAATATGTTGTGGTGCGAGTTTTAACATACACTGCGGGACCAGCAAGCCA") ;
    stable.push_back("CCAAAATCAACTCCTCGAGGAAGTAAATGCGATGGCTGTGTTACAGCGTGTATCGCGTCATGTCCTTGTTGCTGTAATTTCCACTGTCAGGACGATGAAAGCGCCGGGACGAAGGGCCATCAGGGGCTACTCCAGACCGACGAGTTCCCTCTCTGCCAGAAAATATGTTGTGGTGCTAGTTTTAACATACACTGCGGGACCAGCAAGCCA") ;
    stable.push_back("CCAAAATCAACTCCTCGAGGAAGTAAATGCGATGGCTGTGTTACAGCGTGTATCGCGTCATGTCCTTGTTGCTGTAATTTCCACTGTCAGGACGATGAAAGCGCCGGGACGAAGGGCCATCAGGGGCTACTCCAGACCGACGAGTTCCCTCTCTGCCAGAAAATATGTTGTGGTGCTAGTTTTAACATACACTGCGGGACCAGCAAGCCA") ;
    stable.push_back("CCAAAATCAACTCCTCGAGGAAGTAAATGCGATGGCTGTGTTACAGCGTGTATCGCGTCATGTCCTTGTTGCTGTAATTTCCACTGTCAGGACGATGAAAGCGCCGGGACGAAGGGCCATCAGGGGCTACTCCAGACCGACGAGTTCCCTCTCTGCCAGAAAATATGTTGTGGTGCGAGTTTTAACATACACTGCGGGACCAGCAAGCCA") ; 
    stable.push_back("CCAAAATCAACTCCTCGAGGAAGTAAATGCGATGGCTGTGTTACAGCGTGTATCGCGTCATGTCCTTGTTGCTGTAATTTCCACTGTCAGGACGATGAAAGCGCCGGGACGAAGGGCCATCAGGGGCTACTCCAGACCGACGAGTTCCCTCTCTGCCAGAAAATATGTTGTGGTGCGAGTTTTAACATACACTGCGGGACCAGCAAGCCA") ;
    stable.push_back("CCAAAATCAACTCCTCGAGGAAGTAAATGCGATGGCTGTGTTACAGCGTGTATCGCGTCATGTCCTTGTTGCTGTAATTTCCACTGTCAGGACGATGAAAGCGCCGGGACGAAGGGCCATCAGTGGCTACTCCAGACCGACGAGTTCCCTCTCTGCCGGAAAATATGTCGTGGTGCGAGTTTTAACATACACTGCGGGACCAGCAAGCCA") ;
    stable.push_back("CCAAAATCAACTCCTCGAGGAAGTAAATGCGATGGCTGTGTTACAGCGTGTATCGCGTCATGTCCTTGTTGCTGTAATTTCCACTGTCAGGACGATGAAAGCGCCGGGACGAAGGGCCATCAGGGGCTACTCCAGACCGACGAGTTCCCTCTCTGCCAGAAAATATGTTGTGGTGCGAGTTTTAACATACACTGCGGGACCAGCAAGCCA") ;


////////////////////////////////////////////////////////////



    vector<int> dict ;//Remembers random values

    dict.push_back( mtrand1.randInt( 9 ) ) ;

    int dummy = 0 ;

    bool found = false ;

    int counter = 0 ;

    int randomvalue ;

    while( counter < 5 )
    {               
        dummy = dict.size() ;

        found = false ;

        randomvalue = mtrand1.randInt( 9 ) ;    

        for ( int j = 0 ; j < dummy ; j++ )
        {
            if ( dict[j] == randomvalue )
            {
                found = true ;

                break ;
            }
        }

        if(!found)
        {           
            dict.push_back( randomvalue ) ;

            stable[randomvalue] = "flag" ;      

            counter++ ; 
        }       
    }

    stable.erase( remove( stable.begin(), stable.end(), "flag" ), stable.end() );



/////////////////////////////////////////////////////////

cout << "This is the new stable array: " << endl ;

for( int i = 0 ; i < stable.size() ; i++ )
{
    cout << stable[i] << endl ; 
}

return 0;

}

I would suggest using the algorithm described in Programming Pearls for this problem (Algorithm S from Knuth's Seminumerical Algorithms ). 我建议使用在《 编程Pearls》中描述的算法来解决此问题(来自Knuth的Seminumerical Algorithms的算法S)。 The idea is to select elements in order with probability s/r where s is the number remaining to select and r is the number of elements remaining. 想法是按概率s / r顺序选择元素,其中s是要选择的剩余数量,r是要剩余的元素数量。 This selects m elements from n in order with every element having an equal chance of being selected. 这从n中顺序选择m个元素,每个元素都有相等的机会被选中。

This implementation uses copy_if to copy selected elements to a new vector. 此实现使用copy_if将所选元素复制到新向量。 This will likely usually be more efficient than trying to remove elements from the original vector as you avoid all of the moving down of elements within the vector when you erase. 这通常比尝试从原始向量中删除元素更有效,因为这样可以避免擦除时向量中所有元素向下移动。 You could use move_iterators with C++11 if you don't need to preserve the original vector to avoid additional element copies. 如果不需要保留原始向量以避免额外的元素复制,则可以在C ++ 11中使用move_iterators。

#include <algorithm>
#include <iostream>
#include <iterator>
#include <random>
#include <string>
#include <vector>

using namespace std;

template<typename I1, typename I2, typename Engine>
I2 copyRandomM(I1 first, I1 last, I2 dest, int m, Engine& eng) {
    int n = distance(first, last);
    return copy_if(first, last, dest, [&](decltype(*first)) { 
        return uniform_int_distribution<>(0, --n)(eng) < m ? --m, true : false; });
}

int main() {
    mt19937 engine;
    auto v = vector<string>{ "orange", "apple", "banana", "pear", "kiwi", "tangerine" };
    vector<string> selection(4);
    copyRandomM(begin(v), end(v), begin(selection), selection.size(), engine);
    copy(begin(selection), end(selection), ostream_iterator<string>(cout, " "));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM