【问题标题】:how to remove random elements from a vector without repeating them and preserving element order? C++如何从向量中删除随机元素而不重复它们并保留元素顺序? C++
【发布时间】:2013-10-29 01:16:55
【问题描述】:

我想从向量中删除确定数量的随机元素,同时保留元素顺序。我为此目的编写了这段代码,当我为小向量运行它时它运行良好,但是当我为大向量运行它时(总共 1000 个元素删除 200 个随机元素),它似乎无法正常工作。

谁能给我一个正确的方向?

#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;

}

【问题讨论】:

  • “似乎无法正常工作”是什么意思?
  • mtrand1.randInt( 9 ) 返回什么?
  • @j_random_hacker 此代码是一个更大程序的一部分。该程序在删除 200 个元素后进行突变鲁棒性计算。这个过程重复 500 次。这个数量应该随着时间而改变,但在这段代码中,它在这 500 次迭代中保持不变。
  • @Beta 它返回一个从0到9的随机数。
  • 如果你需要移除随机元素,为什么不从向量数组中的 200 个随机位置移除呢?

标签: c++ random vector elements preserve


【解决方案1】:

我建议使用 Programming Pearls 中描述的算法来解决这个问题(来自 Knuth 的 半数字算法 的算法 S)。这个想法是按照概率 s/r 按顺序选择元素,其中 s 是要选择的剩余数量,r 是剩余元素的数量。这会按顺序从 n 中选择 m 个元素,每个元素被选中的机会均等。

此实现使用 copy_if 将选定元素复制到新向量。这通常可能比尝试从原始向量中删除元素更有效,因为您在擦除时避免了向量内元素的所有向下移动。如果您不需要保留原始向量以避免额外的元素副本,则可以将 move_iterators 与 C++11 一起使用。

#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, " "));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    相关资源
    最近更新 更多