基本上,我们有一项家庭作业,以c ++创建一个程序,该程序打开一个文本文件(“ input.txt ”),并输出到另一个文件(“ output.txt” ”),使用递归算法对输入文件的文本行进行排列。
我曾尝试实现递归函数,但似乎无法将其包裹住。我想输入和输出文件虽然不错(我认为)。
任何建议将不胜感激:)
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
string data;
string file_contents;
string permute()
{
string result;
ifstream inFile;
inFile.open("input.txt");
int a = 0;
while (getline(inFile, file_contents))
{
a++;
}
if (a == 1)
{
ofstream OutFile;
}
else
{
ofstream OutFile;
}
return result;
}//perm
void accessFile()
{
ifstream inFile;
inFile.open("input.txt");
if (!inFile.is_open())
{
cout << "Error openning input file" << endl;
}
else
{
while (getline(inFile, data))
{
file_contents += data;
file_contents.push_back('\n');
}
inFile.close();
}
ofstream OutFile;
OutFile.open("output.txt");
if(OutFile.fail())
{
cout << "Error openning output file." << endl;
}
else
{
OutFile << file_contents;
permute();
OutFile.close();
}
}//File
int main()
{
cout << "do you want to run the program?" << endl;
string input;
cin >> input;
if (input == "yes")
{
accessFile();
}
else
{
exit;
}
return 0;
}//main
让我们说输入是:
Line One
Line Two
Line Three
预期输出为:
Line One
Line Two
Line Three
Line One
Line Three
Line Two
Line Two
Line One
Line Three
Line Two
Line Three
Line One
Line Three
Line One
Line Two
Line Three
Line Two
Line One
答案 0 :(得分:1)
我已将代码修改为@cmdLP建议。为了利用C ++语言的功能,您应该使用bool next_permutation (BidirectionalIterator first, BidirectionalIterator last);
函数模板。
如果您不知道它是如何工作的,则应查看http://www.cplusplus.com/reference/algorithm/next_permutation/
我不得不将file_contents
的类型更改为std::vector<string>
,因为next_permutation
不能与单个字符串一起使用。
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm> // std::next_permutation
using namespace std;
string data;
std::vector<string> file_contents;
string permute() {
string result;
do {
for(auto a: file_contents)
result += a + " ";
result += "\n";
} while ( std::next_permutation(file_contents.begin(),file_contents.end()) );
return result;
}
void accessFile() {
ifstream inFile;
inFile.open("input.txt");
if (!inFile.is_open())
{
cout << "Error openning input file" << endl;
}
else
{
while (getline(inFile, data))
{
file_contents.push_back(data);
}
inFile.close();
}
ofstream OutFile;
OutFile.open("output.txt");
if(OutFile.fail())
{
cout << "Error openning output file." << endl;
}
else
{
// OutFile << file_contents;
string result = permute();
OutFile << result;
OutFile.close();
}
}//File
int main()
{
cout << "do you want to run the program?" << endl;
string input;
cin >> input;
if (input == "yes")
{
accessFile();
}
else
{
exit(1);
}
return 0;
}//main
答案 1 :(得分:0)
如@cmdLP建议。在C ++中,我们可以使用C ++的功能,尤其是算法。放弃原始示例,这里提供了更现代的C ++解决方案:
// We want to use the stream input iterator and beeing able to read a complete line (and not words only)
class CompleteLine {
public:
// Friend: Overload extraction operator for this class. Read complete line
friend std::istream& operator>>(std::istream& is, CompleteLine& cl) {std::getline(is, cl.completeLine); return is; }
operator std::string() const { return completeLine; } // Return the previously read line
protected:
std::string completeLine{};
};
// Permute the lines of a file
void permute(const std::string& inFileName, const std::string& outFileName)
{
std::ifstream inFileStream{ inFileName }; // Open the input file (will be closed by destructor)
if (!inFileStream) { // ! is overloaded
std::cerr << "Could Not open infile: '" << inFileName << "'\n";
}
else {
// Read all lines into a vector of strings. The string will contain the whole line
std::vector<std::string> fileAsLines{ std::istream_iterator<CompleteLine>(inFileStream),std::istream_iterator<CompleteLine>() };
std::ofstream outFileStream{ outFileName }; // Open the input file (will be closed by destructor)
if (!outFileStream) { // ! is overloaded
std::cerr << "Could Not open outfile: '" << outFileName << "'\n";
}
else {
// Sort strings (lines in file)
std::sort(fileAsLines.begin(), fileAsLines.end());
do {
// Ouput complete vector, so all strings (lines) of the file
std::copy(fileAsLines.begin(), fileAsLines.end(), std::ostream_iterator<std::string>(outFileStream, "\n"));
outFileStream << '\n'; // To make it easier to read the output
} while (std::next_permutation(fileAsLines.begin(), fileAsLines.end())); // Next permutation of vector
}
}
}
希望这会有所帮助
答案 2 :(得分:0)
正如其他人所建议的,可以使用'std :: next_permutation'解决问题。 但是我认为@Mustafa Kalzi想到的是对如何创建这种算法有更好的理解。 我知道这是一个过大的问题,但是我发现这个问题很有趣,可以解决,并且可以算是数学问题。 考虑到“ std :: next_permutation”的某些缺点,我为置换问题创建了另一种通用算法。
我们已经做出了很多努力,将排列作为一个对象,该排列仅取决于可能的配置数量并且可以通过, 比较并最终由几个不同的对象使用,在那里可以为用户提供几乎完整的控制!
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
/* Copyright (C) 2019 AKL.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*just a simple rotator for an array of size(size_) elements.
std::rotate is to cumbersome and needs sorting*/
template<typename value_t__, typename size_t__>
void rotation(value_t__* , size_t__ size_, decltype(size_) = 1);
/*an all encompassing function template for finding permutations of an array elements
based on the inputed configuration value.
since the it is ignorant to the contents of the array, it can be used with number of
pointers but not for the iterators.
in the case of iterators it is best to first fill a normal array with consecutive numbers
then use the content as an index for operator[] of any container!
please note that the main overhead is to create and fill the input array for each permutation
but as it was stated contents remain untouched in contrast to std::next_permutation*/
template<typename value_t__, typename size_t__>
void permutation(value_t__* , size_t__ size_,
decltype(size_));
/*Optionally an all-in-one class template to have incremental/decremental fully functional counter-like object
which also includes the index array.
in contrast to std::next_permutation, main advantages are to have a method to know how many permutations
have been passed by comparing it to other objects/values like a value and going forward and backward
through permutations and not having to sort any thing before hand as it not sensitive to contents*/
template<typename size_t__ = std::size_t>
class permutations {
public:
/*most useful and many of the required member functions for such classes
***please note that extra safety mechanisms like range check and safety against 0 size are not included***
but these are easy to overcome by the user, so one can choose to optimize the usage for speed or safety!*/
permutations(size_t__);
permutations(const permutations&);
void set_configuration(size_t__);
size_t__& operator[](size_t__);
size_t__ operator[](size_t__) const;
size_t__ get_possibilities() const;
permutations& operator++();
permutations& operator--();
permutations operator++(int);
permutations operator--(int);
operator size_t__() const;
~permutations();
private:
size_t__ size_v;
size_t__ possibilities;
size_t__ configuration;
size_t__* index;
};
/*assuming that the first argument to the program is the name of
input file and the second argument would be the name of output file
in posix it can be executed like:
./program_name input_file_name.txt output_file_name.txt
*/
int main(int argc, char* argv[]) {
//checking if the right arguments have been entered
if ((not argc) or (argc > 3)) {
std::cout << "wrong number of arguments " << argc - 1 << "should be 2"
<< std::endl;
return -1;
}
//opening the input file;
std::ifstream in_file(argv[1]);
//checking if the file is opened correctly
if (not in_file.is_open()) {
std::cout << "can't open input file" << argv[1] << std::endl;
return -1;
}
//creating a vector for lines
std::vector<std::string> lines;
//filling the string vector by the reading from the input file lines
for (std::string one_line; std::getline(in_file, one_line);
lines.push_back(one_line))
;
//creating an integer and filling it with the number of lines
const std::size_t lines_count(lines.size());
//permutations class templates are not able to handle 0 input so lets produce an error if that is the case
if (not lines_count) {
std::cout << argv[1] << " has zero lines!" << std::endl;
return -1;
}
std::cout << argv[1] << " has " << lines_count << " lines" << std::endl;
//creating a permutations object to find right vector index for permutations
permutations<> permutation_counter(lines_count);
//getting the number of total possible permutations. optional!
const std::size_t possible_permutations(
permutation_counter.get_possibilities());
std::cout << "number of possible permutations is " << possible_permutations
<< std::endl;
/*alternatively this also can be done with permutation function
one only needs to first create an array for the indexes but
filling the index array might be tedious*/
//creating and opening the output file
std::ofstream out_file(argv[2]);
//checking if the file is opened correctly
if (not out_file.is_open()) {
std::cout << "can't open output file" << argv[2] << std::endl;
return -1;
}
//it is good to know how much of work is done for large files later!
std::size_t done_percentage(0);
//everything is set. now lets start going forward trough the permutations and writing to the output file!
do {
out_file << "********** permutation " << permutation_counter
<< " **********" << std::endl;
for (std::size_t lines_counter(0); lines_counter < lines_count;
out_file << lines[permutation_counter[lines_counter++]]
<< std::endl)
;
out_file << std::endl;
//it is good to know how much of work is done for large files now!
std::size_t done_percentage_now(
(permutation_counter * 100) / possible_permutations);
if (done_percentage_now != done_percentage) {
done_percentage = done_percentage_now;
std::cout << done_percentage << " % is done " << std::endl;
}
} while (++permutation_counter);
/*alternatively --permutation_counter would also work to go backward trough the permutations!
permutation_counter++/permutation_counter-- also work like post increment/decrement operators!
by choosing any number from 0 to possible_permutations it is possible to go half or to a
certain point trough permutations!
in addition by changing index array by using operator[] it would be possible to change any
index there for the respective line or choose to only do the permutation for certain lines
and/or even keep the rest unchanged!*/
std::cout << "!!!finished!!!" << std::endl;
return 0;
}
//definition for all functions.
template<typename value_t__, typename size_t__>
void rotation(value_t__* p_, size_t__ size_, decltype(size_) amount_) {
for (size_t__ begin(0); begin < amount_; ++begin) {
size_t__ index(begin);
value_t__ backup(p_[index]);
for (; (index += amount_) < size_; p_[index - amount_] = p_[index])
;
p_[index - amount_] = backup;
}
}
template<typename value_t__, typename size_t__>
void permutation(value_t__* p_, size_t__ size_,
decltype(size_) configuration_) {
/*above the size of 3 there is a simple regular formula,
which is a combination of rotation of all elements in the current level then
repeating a similar procedure for lower levels by recursive calls*/
if (size_ > 3) {
size_t__ factorial(--size_);
for (size_t__ counter(size_); --counter; factorial *= counter)
;
rotation(p_, size_ + 1, configuration_ / factorial);
permutation(p_ + 1, size_, configuration_ % factorial);
return;
}
/*case of size 3 is not regular but luckily very small so lets cover it as a switch-case statements.
can easily be understood if one writes all the possibilities on a piece of paper (3 cm x 4 cm)*/
if (size_ == 3) {
switch (configuration_) {
case 1:
rotation(p_ + 1, 2);
return;
case 2:
rotation(p_, 3);
return;
case 3:
rotation(p_, 3);
rotation(p_ + 1, 2);
return;
case 4:
rotation(p_, 3, 2);
return;
case 5:
rotation(p_, 3, 2);
rotation(p_ + 1, 2);
return;
default:
if (configuration_ > 5)
permutation(p_, size_, configuration_ % 6);
return;
}
}
//case of size 2 is regular but it is after case of size 3. interestingly it is as tiny as one if statement!
if (size_ == 2 and configuration_ % 2)
rotation(p_, 2);
//there is no permutation for case of size 1 and there is not even a case for lower sizes!
}
template<typename size_t__>
permutations<size_t__>::permutations(size_t__ size_v_) :
size_v(size_v_), possibilities(size_v_), configuration(0), index(
new size_t__[size_v_]) {
for (; --size_v_; possibilities *= index[size_v_] = size_v_)
;
index[0] = 0;
}
template<typename size_t__>
permutations<size_t__>::permutations(const permutations& another_) :
size_v(another_.size_v), possibilities(another_.possibilities), configuration(
another_.configuration), index(new size_t__[size_v]) {
size_t__* another__index(another_.index);
for (size_t__ counter(size_v); counter--; index[counter] =
another__index[counter])
;
}
template<typename size_t__>
void permutations<size_t__>::set_configuration(size_t__ v_) {
configuration = v_;
}
template<typename size_t__>
size_t__&
permutations<size_t__>::operator[](size_t__ index_) {
return index[index_];
}
template<typename size_t__>
size_t__ permutations<size_t__>::operator[](size_t__ index_) const {
return index[index_];
}
template<typename size_t__>
size_t__ permutations<size_t__>::get_possibilities() const {
return possibilities;
}
template<typename size_t__>
permutations<size_t__>&
permutations<size_t__>::operator++() {
if (not (++configuration < possibilities))
configuration = 0;
for (size_t__ counter(size_v); counter--; index[counter] = counter)
;
permutation(index, size_v, configuration);
return *this;
}
template<typename size_t__>
permutations<size_t__>&
permutations<size_t__>::operator--() {
if (not configuration--)
configuration = possibilities - 1;
for (size_t__ counter(size_v); counter--; index[counter] = counter)
;
permutation(index, size_v, configuration);
return *this;
}
template<typename size_t__>
permutations<size_t__> permutations<size_t__>::operator++(int) {
permutations back(*this);
++(*this);
return back;
}
template<typename size_t__>
permutations<size_t__> permutations<size_t__>::operator--(int) {
permutations back(*this);
--(*this);
return back;
}
template<typename size_t__>
permutations<size_t__>::operator size_t__() const {
return configuration;
}
template<typename size_t__>
permutations<size_t__>::~permutations() {
delete[] index;
}
给出输入文件:
line 0
line 1
line 2
line 3
line 4
结果输出文件:
********** permutation 0 **********
line 0
line 1
line 2
line 3
line 4
********** permutation 1 **********
line 0
line 1
line 2
line 4
line 3
********** permutation 2 **********
line 0
line 1
line 3
line 4
line 2
********** permutation 3 **********
line 0
line 1
line 3
line 2
line 4
********** permutation 4 **********
line 0
line 1
line 4
line 3
line 2
********** permutation 5 **********
line 0
line 1
line 4
line 2
line 3
********** permutation 6 **********
line 0
line 2
line 3
line 4
line 1
********** permutation 7 **********
line 0
line 2
line 3
line 1
line 4
********** permutation 8 **********
line 0
line 2
line 4
line 1
line 3
********** permutation 9 **********
line 0
line 2
line 4
line 3
line 1
********** permutation 10 **********
line 0
line 2
line 1
line 4
line 3
********** permutation 11 **********
line 0
line 2
line 1
line 3
line 4
********** permutation 12 **********
line 0
line 3
line 4
line 1
line 2
********** permutation 13 **********
line 0
line 3
line 4
line 2
line 1
********** permutation 14 **********
line 0
line 3
line 1
line 2
line 4
********** permutation 15 **********
line 0
line 3
line 1
line 4
line 2
********** permutation 16 **********
line 0
line 3
line 2
line 1
line 4
********** permutation 17 **********
line 0
line 3
line 2
line 4
line 1
********** permutation 18 **********
line 0
line 4
line 2
line 3
line 1
********** permutation 19 **********
line 0
line 4
line 2
line 1
line 3
********** permutation 20 **********
line 0
line 4
line 3
line 1
line 2
********** permutation 21 **********
line 0
line 4
line 3
line 2
line 1
********** permutation 22 **********
line 0
line 4
line 1
line 3
line 2
********** permutation 23 **********
line 0
line 4
line 1
line 2
line 3
********** permutation 24 **********
line 1
line 2
line 3
line 4
line 0
********** permutation 25 **********
line 1
line 2
line 3
line 0
line 4
********** permutation 26 **********
line 1
line 2
line 4
line 0
line 3
********** permutation 27 **********
line 1
line 2
line 4
line 3
line 0
********** permutation 28 **********
line 1
line 2
line 0
line 4
line 3
********** permutation 29 **********
line 1
line 2
line 0
line 3
line 4
********** permutation 30 **********
line 1
line 3
line 4
line 0
line 2
********** permutation 31 **********
line 1
line 3
line 4
line 2
line 0
********** permutation 32 **********
line 1
line 3
line 0
line 2
line 4
********** permutation 33 **********
line 1
line 3
line 0
line 4
line 2
********** permutation 34 **********
line 1
line 3
line 2
line 0
line 4
********** permutation 35 **********
line 1
line 3
line 2
line 4
line 0
********** permutation 36 **********
line 1
line 4
line 0
line 2
line 3
********** permutation 37 **********
line 1
line 4
line 0
line 3
line 2
********** permutation 38 **********
line 1
line 4
line 2
line 3
line 0
********** permutation 39 **********
line 1
line 4
line 2
line 0
line 3
********** permutation 40 **********
line 1
line 4
line 3
line 2
line 0
********** permutation 41 **********
line 1
line 4
line 3
line 0
line 2
********** permutation 42 **********
line 1
line 0
line 3
line 4
line 2
********** permutation 43 **********
line 1
line 0
line 3
line 2
line 4
********** permutation 44 **********
line 1
line 0
line 4
line 2
line 3
********** permutation 45 **********
line 1
line 0
line 4
line 3
line 2
********** permutation 46 **********
line 1
line 0
line 2
line 4
line 3
********** permutation 47 **********
line 1
line 0
line 2
line 3
line 4
********** permutation 48 **********
line 2
line 3
line 4
line 1
line 0
********** permutation 49 **********
line 2
line 3
line 4
line 0
line 1
********** permutation 50 **********
line 2
line 3
line 1
line 0
line 4
********** permutation 51 **********
line 2
line 3
line 1
line 4
line 0
********** permutation 52 **********
line 2
line 3
line 0
line 1
line 4
********** permutation 53 **********
line 2
line 3
line 0
line 4
line 1
********** permutation 54 **********
line 2
line 4
line 1
line 0
line 3
********** permutation 55 **********
line 2
line 4
line 1
line 3
line 0
********** permutation 56 **********
line 2
line 4
line 0
line 3
line 1
********** permutation 57 **********
line 2
line 4
line 0
line 1
line 3
********** permutation 58 **********
line 2
line 4
line 3
line 0
line 1
********** permutation 59 **********
line 2
line 4
line 3
line 1
line 0
********** permutation 60 **********
line 2
line 1
line 0
line 3
line 4
********** permutation 61 **********
line 2
line 1
line 0
line 4
line 3
********** permutation 62 **********
line 2
line 1
line 3
line 4
line 0
********** permutation 63 **********
line 2
line 1
line 3
line 0
line 4
********** permutation 64 **********
line 2
line 1
line 4
line 3
line 0
********** permutation 65 **********
line 2
line 1
line 4
line 0
line 3
********** permutation 66 **********
line 2
line 0
line 4
line 1
line 3
********** permutation 67 **********
line 2
line 0
line 4
line 3
line 1
********** permutation 68 **********
line 2
line 0
line 1
line 3
line 4
********** permutation 69 **********
line 2
line 0
line 1
line 4
line 3
********** permutation 70 **********
line 2
line 0
line 3
line 1
line 4
********** permutation 71 **********
line 2
line 0
line 3
line 4
line 1
********** permutation 72 **********
line 3
line 4
line 2
line 0
line 1
********** permutation 73 **********
line 3
line 4
line 2
line 1
line 0
********** permutation 74 **********
line 3
line 4
line 0
line 1
line 2
********** permutation 75 **********
line 3
line 4
line 0
line 2
line 1
********** permutation 76 **********
line 3
line 4
line 1
line 0
line 2
********** permutation 77 **********
line 3
line 4
line 1
line 2
line 0
********** permutation 78 **********
line 3
line 2
line 0
line 1
line 4
********** permutation 79 **********
line 3
line 2
line 0
line 4
line 1
********** permutation 80 **********
line 3
line 2
line 1
line 4
line 0
********** permutation 81 **********
line 3
line 2
line 1
line 0
line 4
********** permutation 82 **********
line 3
line 2
line 4
line 1
line 0
********** permutation 83 **********
line 3
line 2
line 4
line 0
line 1
********** permutation 84 **********
line 3
line 0
line 1
line 4
line 2
********** permutation 85 **********
line 3
line 0
line 1
line 2
line 4
********** permutation 86 **********
line 3
line 0
line 4
line 2
line 1
********** permutation 87 **********
line 3
line 0
line 4
line 1
line 2
********** permutation 88 **********
line 3
line 0
line 2
line 4
line 1
********** permutation 89 **********
line 3
line 0
line 2
line 1
line 4
********** permutation 90 **********
line 3
line 1
line 2
line 0
line 4
********** permutation 91 **********
line 3
line 1
line 2
line 4
line 0
********** permutation 92 **********
line 3
line 1
line 0
line 4
line 2
********** permutation 93 **********
line 3
line 1
line 0
line 2
line 4
********** permutation 94 **********
line 3
line 1
line 4
line 0
line 2
********** permutation 95 **********
line 3
line 1
line 4
line 2
line 0
********** permutation 96 **********
line 4
line 1
line 2
line 3
line 0
********** permutation 97 **********
line 4
line 1
line 2
line 0
line 3
********** permutation 98 **********
line 4
line 1
line 3
line 0
line 2
********** permutation 99 **********
line 4
line 1
line 3
line 2
line 0
********** permutation 100 **********
line 4
line 1
line 0
line 3
line 2
********** permutation 101 **********
line 4
line 1
line 0
line 2
line 3
********** permutation 102 **********
line 4
line 2
line 3
line 0
line 1
********** permutation 103 **********
line 4
line 2
line 3
line 1
line 0
********** permutation 104 **********
line 4
line 2
line 0
line 1
line 3
********** permutation 105 **********
line 4
line 2
line 0
line 3
line 1
********** permutation 106 **********
line 4
line 2
line 1
line 0
line 3
********** permutation 107 **********
line 4
line 2
line 1
line 3
line 0
********** permutation 108 **********
line 4
line 3
line 0
line 1
line 2
********** permutation 109 **********
line 4
line 3
line 0
line 2
line 1
********** permutation 110 **********
line 4
line 3
line 1
line 2
line 0
********** permutation 111 **********
line 4
line 3
line 1
line 0
line 2
********** permutation 112 **********
line 4
line 3
line 2
line 1
line 0
********** permutation 113 **********
line 4
line 3
line 2
line 0
line 1
********** permutation 114 **********
line 4
line 0
line 2
line 3
line 1
********** permutation 115 **********
line 4
line 0
line 2
line 1
line 3
********** permutation 116 **********
line 4
line 0
line 3
line 1
line 2
********** permutation 117 **********
line 4
line 0
line 3
line 2
line 1
********** permutation 118 **********
line 4
line 0
line 1
line 3
line 2
********** permutation 119 **********
line 4
line 0
line 1
line 2
line 3
控制台对话和消息:
./program input.txt output.txt
input.txt has 5 lines
number of possible permutations is 120
1 % is done
2 % is done
3 % is done
4 % is done
5 % is done
6 % is done
7 % is done
8 % is done
9 % is done
10 % is done
11 % is done
12 % is done
13 % is done
14 % is done
15 % is done
16 % is done
17 % is done
18 % is done
19 % is done
20 % is done
21 % is done
22 % is done
23 % is done
24 % is done
25 % is done
26 % is done
27 % is done
28 % is done
29 % is done
30 % is done
31 % is done
32 % is done
33 % is done
34 % is done
35 % is done
36 % is done
37 % is done
38 % is done
39 % is done
40 % is done
41 % is done
42 % is done
43 % is done
44 % is done
45 % is done
46 % is done
47 % is done
48 % is done
49 % is done
50 % is done
51 % is done
52 % is done
53 % is done
54 % is done
55 % is done
56 % is done
57 % is done
58 % is done
59 % is done
60 % is done
61 % is done
62 % is done
63 % is done
64 % is done
65 % is done
66 % is done
67 % is done
68 % is done
69 % is done
70 % is done
71 % is done
72 % is done
73 % is done
74 % is done
75 % is done
76 % is done
77 % is done
78 % is done
79 % is done
80 % is done
81 % is done
82 % is done
83 % is done
84 % is done
85 % is done
86 % is done
87 % is done
88 % is done
89 % is done
90 % is done
91 % is done
92 % is done
93 % is done
94 % is done
95 % is done
96 % is done
97 % is done
98 % is done
99 % is done
!!!finished!!!
该代码具有很好的注释性和自我解释能力。在主函数之前的开头声明函数和类模板是解决此类问题的另一种通用方法。主要功能中的其余代码用于展示如何使用这些模板,并且其结构或多或少类似于其他人所做的。最后,在主函数之后最后给出了函数的完整定义。
理解该问题的关键是如何处理不规则的4个变量,因为3!(3 x 2 x 6)大于变量(3)的数量,而2!(2 x 1)大于不大于变量(2)的数量,因此很难确定如何找到4个变量以下情况的旋转和排列。但是有趣的是,超过该阈值将变得非常规则和容易!
基于表示可能排列的数字,人们只需找到旋转值和先前级别的排列值。例如,考虑4变量的情况,我将其指定为问题的4级,并且是User对递归函数的第一次调用。共4!(4 x 3 x 2 x 1)= 24种可能性。给定数字20作为某个置换的表示,将20除以3!(6)即可找到旋转的表示,并将20的余数除以3!(6)作为级别3置换的表示,是对函数本身的第二次调用和第一次递归调用。
对于'std :: next_permutation',一定不要忘记必须首先对容器进行排序,否则它不会产生所有排列。这也意味着排列的排列是在用户控制之外的,特别是如果希望具有与原始输入相同的第一配置时。而且它也没有提供一种方法来了解排列演化的状态。
提供的此替代解决方案(在GNU LGPL版本2和更高版本中)还封装了一些其他有用的功能。我能想到的一个主要缺点是无法使用迭代器。在为每个排列填充索引数组而导致的开销方面,除去(仅从主要功能而不是模板中)主要功能(进度报告等)并针对10行的输入文件执行了速度测试之后,此方法与使用'std :: next_permutation'(57.2 vs 57.9秒)之间几乎没有差异。还需要注意的是,与写入文件和流所需的过程相比,这两种算法所需的过程可能都太少了,从而使我的速度测试变得毫无用处!
如果这不是他的初衷,或者我的代码不符合他的喜好,我向@Mustafa Kalzi致歉!
请随时发表评论,提供建议/更正并提出问题!祝好运!
答案 3 :(得分:0)
@MustafaKalzi,为便于比较和简化起见,我编辑了代码,改为使用std :: next_permutation。这也很容易理解,如果您更倾向于使用标准库,则可以使用它。 排列计数和进度报告已被省略,您以后可以轻松地添加它。
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
/*assuming that the first argument to the program is the name of
input file and the second argument would be the name of output file*/
int main(int argc, char* argv[]) {
//checking if the right arguments have been entered
if ((not argc) or (argc > 3)) {
std::cerr << "wrong number of arguments " << argc - 1 << "should be 2"
<< std::endl;
return -1;
}
//opening the input file;
std::ifstream in_file(argv[1]);
//checking if the file is opened correctly
if (not in_file.is_open()) {
std::cerr << "can't open input file" << argv[1] << std::endl;
return -1;
}
//creating a vector for lines
std::vector<std::string> lines;
//filling the string vector by the reading from the input file lines
for (std::string one_line; std::getline(in_file, one_line);
lines.push_back(one_line))
;
//creating an integer and filling it with the number of lines
const std::size_t lines_count(lines.size());
//producing an error if there is no line in the file
if (not lines_count) {
std::cerr << argv[1] << " has zero lines!" << std::endl;
return -1;
}
std::cout << argv[1] << " has " << lines_count << " lines" << std::endl;
//sorting the vector in order to use std::next permutation afterwards
std::sort(lines.begin(), lines.end());
//creating and opening the output file
std::ofstream out_file(argv[2]);
//checking if the file is opened correctly
if (not out_file.is_open()) {
std::cerr << "can't open output file" << argv[2] << std::endl;
return -1;
}
//everything is set. now lets start going forward trough the permutations and writing to the output file!
do {
for (std::size_t lines_counter(0); lines_counter < lines_count;
out_file << lines[lines_counter++] << std::endl)
;
out_file << std::endl;
} while (std::next_permutation(lines.begin(), lines.end()));
std::cout << "!!!finished!!!" << std::endl;
return 0;
}
输入文件
line 0
line 1
line 2
line 3
line 4
输出文件
line 0
line 1
line 2
line 3
line 4
line 0
line 1
line 2
line 4
line 3
line 0
line 1
line 3
line 2
line 4
line 0
line 1
line 3
line 4
line 2
line 0
line 1
line 4
line 2
line 3
line 0
line 1
line 4
line 3
line 2
line 0
line 2
line 1
line 3
line 4
line 0
line 2
line 1
line 4
line 3
line 0
line 2
line 3
line 1
line 4
line 0
line 2
line 3
line 4
line 1
line 0
line 2
line 4
line 1
line 3
line 0
line 2
line 4
line 3
line 1
line 0
line 3
line 1
line 2
line 4
line 0
line 3
line 1
line 4
line 2
line 0
line 3
line 2
line 1
line 4
line 0
line 3
line 2
line 4
line 1
line 0
line 3
line 4
line 1
line 2
line 0
line 3
line 4
line 2
line 1
line 0
line 4
line 1
line 2
line 3
line 0
line 4
line 1
line 3
line 2
line 0
line 4
line 2
line 1
line 3
line 0
line 4
line 2
line 3
line 1
line 0
line 4
line 3
line 1
line 2
line 0
line 4
line 3
line 2
line 1
line 1
line 0
line 2
line 3
line 4
line 1
line 0
line 2
line 4
line 3
line 1
line 0
line 3
line 2
line 4
line 1
line 0
line 3
line 4
line 2
line 1
line 0
line 4
line 2
line 3
line 1
line 0
line 4
line 3
line 2
line 1
line 2
line 0
line 3
line 4
line 1
line 2
line 0
line 4
line 3
line 1
line 2
line 3
line 0
line 4
line 1
line 2
line 3
line 4
line 0
line 1
line 2
line 4
line 0
line 3
line 1
line 2
line 4
line 3
line 0
line 1
line 3
line 0
line 2
line 4
line 1
line 3
line 0
line 4
line 2
line 1
line 3
line 2
line 0
line 4
line 1
line 3
line 2
line 4
line 0
line 1
line 3
line 4
line 0
line 2
line 1
line 3
line 4
line 2
line 0
line 1
line 4
line 0
line 2
line 3
line 1
line 4
line 0
line 3
line 2
line 1
line 4
line 2
line 0
line 3
line 1
line 4
line 2
line 3
line 0
line 1
line 4
line 3
line 0
line 2
line 1
line 4
line 3
line 2
line 0
line 2
line 0
line 1
line 3
line 4
line 2
line 0
line 1
line 4
line 3
line 2
line 0
line 3
line 1
line 4
line 2
line 0
line 3
line 4
line 1
line 2
line 0
line 4
line 1
line 3
line 2
line 0
line 4
line 3
line 1
line 2
line 1
line 0
line 3
line 4
line 2
line 1
line 0
line 4
line 3
line 2
line 1
line 3
line 0
line 4
line 2
line 1
line 3
line 4
line 0
line 2
line 1
line 4
line 0
line 3
line 2
line 1
line 4
line 3
line 0
line 2
line 3
line 0
line 1
line 4
line 2
line 3
line 0
line 4
line 1
line 2
line 3
line 1
line 0
line 4
line 2
line 3
line 1
line 4
line 0
line 2
line 3
line 4
line 0
line 1
line 2
line 3
line 4
line 1
line 0
line 2
line 4
line 0
line 1
line 3
line 2
line 4
line 0
line 3
line 1
line 2
line 4
line 1
line 0
line 3
line 2
line 4
line 1
line 3
line 0
line 2
line 4
line 3
line 0
line 1
line 2
line 4
line 3
line 1
line 0
line 3
line 0
line 1
line 2
line 4
line 3
line 0
line 1
line 4
line 2
line 3
line 0
line 2
line 1
line 4
line 3
line 0
line 2
line 4
line 1
line 3
line 0
line 4
line 1
line 2
line 3
line 0
line 4
line 2
line 1
line 3
line 1
line 0
line 2
line 4
line 3
line 1
line 0
line 4
line 2
line 3
line 1
line 2
line 0
line 4
line 3
line 1
line 2
line 4
line 0
line 3
line 1
line 4
line 0
line 2
line 3
line 1
line 4
line 2
line 0
line 3
line 2
line 0
line 1
line 4
line 3
line 2
line 0
line 4
line 1
line 3
line 2
line 1
line 0
line 4
line 3
line 2
line 1
line 4
line 0
line 3
line 2
line 4
line 0
line 1
line 3
line 2
line 4
line 1
line 0
line 3
line 4
line 0
line 1
line 2
line 3
line 4
line 0
line 2
line 1
line 3
line 4
line 1
line 0
line 2
line 3
line 4
line 1
line 2
line 0
line 3
line 4
line 2
line 0
line 1
line 3
line 4
line 2
line 1
line 0
line 4
line 0
line 1
line 2
line 3
line 4
line 0
line 1
line 3
line 2
line 4
line 0
line 2
line 1
line 3
line 4
line 0
line 2
line 3
line 1
line 4
line 0
line 3
line 1
line 2
line 4
line 0
line 3
line 2
line 1
line 4
line 1
line 0
line 2
line 3
line 4
line 1
line 0
line 3
line 2
line 4
line 1
line 2
line 0
line 3
line 4
line 1
line 2
line 3
line 0
line 4
line 1
line 3
line 0
line 2
line 4
line 1
line 3
line 2
line 0
line 4
line 2
line 0
line 1
line 3
line 4
line 2
line 0
line 3
line 1
line 4
line 2
line 1
line 0
line 3
line 4
line 2
line 1
line 3
line 0
line 4
line 2
line 3
line 0
line 1
line 4
line 2
line 3
line 1
line 0
line 4
line 3
line 0
line 1
line 2
line 4
line 3
line 0
line 2
line 1
line 4
line 3
line 1
line 0
line 2
line 4
line 3
line 1
line 2
line 0
line 4
line 3
line 2
line 0
line 1
line 4
line 3
line 2
line 1
line 0
控制台消息和通讯:
./program input.txt output.txt
input.txt has 5 lines
!!!finished!!!