c++ - C+ + - 函数的两个版本没有产生相同的结果

假设有一个stack填充了0和1 ,我想将mutation_rate_中的许多元素从0改为1,反之亦然,我为此编写了两个函数,但是,其中一个似乎无法正常工作。


#include <stack>


#include <vector>


#include <random>


#include <set>


#include <algorithm>


#include <iostream>



using age_t = unsigned int;



std::stack<age_t> mutate( std::stack<age_t> genome_, age_t mutation_rate_ = 3){


 std::stack<age_t> final_stack;



 // Generate a set, whose elements are the positions at which we perforem the mutation.


 std::set<age_t> positions_to_switch;


 while(positions_to_switch.size() < mutation_rate_){


 positions_to_switch.insert(rand() % genome_.size());


 }



 // Create a counter to go through the stack amd iterator of the set.


 age_t cnt = 0;


 std::set<age_t>::iterator it= positions_to_switch.begin();



 while(genome_.empty()!=true){ // Go through the whole genome_


 if(*it==cnt){ // check if current position in stack matches with


 // element that needs mutation


 if(genome_.top()==1) final_stack.push(0); // mutate


 else final_stack.push(1);


 ++it; // go to next element that needs mutation


 }


 else{ // if no mutation is needed


 final_stack.push(genome_.top());


 }


 genome_.pop(); // go to next element in stack


 ++cnt; // increase counter of stack


 }



 // final stack is in reverse order


 std::stack<age_t> res;


 while(!final_stack.empty()){


 res.push(final_stack.top());


 final_stack.pop();


 }


 return res;


};



std::stack<age_t> mutate_2( std::stack<age_t> genome_, age_t mutation_rate_ = 3){


 std::stack<age_t> final_stack;



 std::vector<age_t> enumeration;


 age_t pos = 0;


 while(enumeration.size() < genome_.size()){


 enumeration.push_back(pos);


 ++pos;


 }


 pos = 0;



 auto rng = std::default_random_engine {};


 std::shuffle(enumeration.begin(), enumeration.end(), rng);



 std::vector<age_t> positions_to_switch;


 while(positions_to_switch.size() < mutation_rate_){


 positions_to_switch.push_back(enumeration[pos]);


 ++pos;


 }



 // Create a counter to go through the stack amd iterator of the set.


 age_t cnt = 0;


 std::vector<age_t>::iterator it= positions_to_switch.begin();



 while(genome_.empty()!=true){ // Go through the whole genome_


 if(*it==cnt){ // check if current position in stack matches with


 // element that needs mutation


 if(genome_.top()==1) final_stack.push(0); // mutate


 else final_stack.push(1);


 ++it; // go to next element that needs mutation


 }


 else{ // if no mutation is needed


 final_stack.push(genome_.top());


 }


 genome_.pop(); // go to next element in stack


 ++cnt; // increase counter of stack


 }



 // final stack is in reverse order


 std::stack<age_t> res;


 while(!final_stack.empty()){


 res.push(final_stack.top());


 final_stack.pop();


 }


 return res;


};



int main(){



 std::stack<age_t> test_stack;


 test_stack.push(1);


 test_stack.push(0);


 test_stack.push(0);


 test_stack.push(0);


 test_stack.push(1);


 test_stack.push(1);



 std::stack<age_t> test_stack_copy = test_stack;


 std::stack<age_t> test_stack_copy_2 = test_stack;



 std::stack<age_t> res = mutate(test_stack);


 std::stack<age_t> res_2 = mutate_2(test_stack);



 std::cout <<"Original Stack:t";


 while(test_stack_copy_2.empty()!=true){


 std::cout << test_stack_copy_2.top();


 test_stack_copy_2.pop();


 }


 std::cout <<"n";



 std::cout <<"Muatet:tt";


 while(res.empty()!=true){


 std::cout << res.top();


 res.pop();


 }


 std::cout <<"n";



 std::cout <<"Muatet_2:t";


 while(res_2.empty()!=true){


 std::cout << res_2.top();


 res_2.pop();


 }


 std::cout <<"n";



 return 0;


}



考虑到测试用例110001mutate返回100111mutate_2返回111101,我设置了mutation_rate_=3,所以初始堆栈的3个元素应该被更改,在mutate_2中,我们可以直接看到mutate已经改变了三个条目,而只改变了其中的两个条目,我相信这与setvector对象如何处理有关,但是我只是找不到错误。

时间:

在第一种情况下,你使用std::set,其中包含按升序排序的排序元素(位置)。

在第二种情况下,带位置的向量不排序。

包含向量的排序


std::sort( positions_to_switch.begin(), positions_to_switch.end() );



std::set的内容会自动排序,但是std::vector的内容不会。

添加排序


 std::sort(positions_to_switch.begin(), positions_to_switch.end());



元素添加部分之后


 std::vector<age_t> positions_to_switch;


 while(positions_to_switch.size() < mutation_rate_){


 positions_to_switch.push_back(enumeration[pos]);


 ++pos;


 }



将解决这个问题。

另一个问题是迭代器it可能在*it==cnt中读完最后一个元素之后,
应该像这样插入it!=positions_to_switch.end() && *it==cnt

...