Takie coś Ci napisałem, nie jest to zbytnio szybkie, lecz zasada działania chyba została zachowana.
Dla Ciebie interesująca jest metoda brute::print_combinations.
#include <iostream>
#include <string>
#include <algorithm>
#include <regex>
#include <cctype>
#include <map>
#include <vector>
class counter{
int num_vals;
unsigned int max_number;
std::vector<unsigned int> count;
bool ended;
public:
counter(unsigned int max, int num_values) : num_vals(num_values),max_number(max),ended(false){
for(int i =0;i<num_values;++i)
count.push_back(0);
}
~counter() = default;
bool end(){return ended;}
counter operator++(int){
for(int i=num_vals-1;i >= 0;--i){
if(count[i]+1>max_number){
count[i] = 0;
}else{
count[i]++;
return *this;
}
}
ended = true;
return *this;
}
int operator[](int num){
return static_cast<unsigned int>(num) < count.size() ? count[num] : 0 ;
}
};
class brute{
static const std::string boolean_value[2];
std::regex regex;
std::smatch match;
std::map<char,char> letters;
bool upcase;
unsigned int length;
public:
brute() : upcase(false),length(0){}
~brute() = default;
bool up(){return upcase;}
unsigned int len(){return length;}
std::map<char,char> &get_map(){return letters;}
void set_upcase(std::string up);
void set_length(std::string l);
void insert_letters(std::string ls);
void insert_change(std::string ch);
void print_combinations();
};
const std::string brute::boolean_value[] = {"true","false"};
void brute::set_upcase(std::string up){
regex = "(\\S+)";
std::regex_match(up,match,regex);
if(match.size() > 0){
std::string str = match[1];
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
upcase = str == "true" ? true : false;
}
}
void brute::set_length(std::string l){
int value = std::stoi(l);
if(value <= 0)return;
length = static_cast<unsigned int>(value);
}
void brute::insert_letters(std::string ls){
for(std::string::iterator iter = ls.begin();iter != ls.end();++iter){
letters[*iter] = 0;
}
}
void brute::insert_change(std::string ch){
regex = "(\\S{1}):(\\S{1}),?";
std::string str = ch;
while(std::regex_search(str,match,regex)){
letters[std::string(match[1]).at(0)] = std::string(match[2]).at(0);
str = match.suffix().str();
}
}
void brute::print_combinations(){
std::vector<char> result(length+1,'\0');
std::vector<char> result_change(length+1,'\0');
std::vector<char> letter;
for(auto m : letters){letter.push_back(m.first);}
if(upcase)for(auto m : letters){letter.push_back(toupper(m.first));}
bool change = false;
for(counter ct(letter.size()-1,length);!ct.end();ct++){
for(unsigned int i =0;i<length;++i){
result_change[i] = result[i] = letter[ct[i]];
if(letters[letter[ct[i]]] != 0){
result_change[i] = letters[letter[ct[i]]];
change = true;
}
}
if(change){
std::cout << result_change.data() << std::endl;
change = false;
}
std::cout << result.data() << std::endl;
}
}
int main(int argc,char **argv){
brute obj;
if(argc > 1)obj.insert_letters(std::string(argv[1]));
if(argc > 2)obj.set_upcase(std::string(argv[2]));
if(argc > 3)obj.set_length(std::string(argv[3]));
if(argc > 4)obj.insert_change(std::string(argv[4]));
const std::string mode = "-s";
bool silent = false;
for(int i=0;i < argc;++i){
if(mode == argv[i]){
silent = true;
break;
}
}
if(!silent){
std::cout << "Possible arguments <letters> <upcase_true> <length> <letter:change,...> " << std::endl;
std::cout << "Silent mode: -s (as last argument)\n";
std::cout << "Example: program abcdef true 3 a:4,b:6 " << std::endl;
std::string uped = obj.up() ? "true" : "false";
std::cout << "\nBrute\n\nupcase?:\t" << uped << std::endl
<< "Length :\t" << obj.len() << std::endl
<< "Letters:\n";
for(auto m : obj.get_map()){
std::cout << m.first << ":\t" << m.second << std::endl;
}
std::cout << "\n-----\nOut:\n-----\n";
}
obj.print_combinations();
}