This question already has answers here:
Implementation of Permutation, Combinations and PowerSet in C++ [duplicate]
(2 answers)
Closed 8 years ago.
I have a function that receives n and k to create all the possible permutations of n choose k, and while it works for most combinations like 5 choose 3 or 3 choose 2, it doesn't for for others like 4 choose 2. I need some help finding and understanding the bug. Thanks for looking.
The function:
void PermGenerator(int n, int k)
{
int d[] = {1,2,3,4,5,6,7,8,9};
sort (d, d+n);
cout << "These are the Possible Permutations: " << endl;
do
{
for (int i = 0; i < k; i++)
{
cout << d[i] << " ";
if (i == k-1) cout << endl;
}
} while (next_permutation(d, d+n));
}
I'm using the next_permutation function. cplusplus
When I try 4 choose 2, I should be getting 12 permutations, instead I get this:
1 2
1 2
1 3
1 3
1 4
1 4
2 1
2 1
2 3
2 3
2 4
2 4
3 1
3 1
3 2
3 2
3 4
3 4
4 1
4 1
4 2
4 2
4 3
4 3
Whereas, 3 choose 2 works perfectly with 6 possible permutations:
1 2
1 3
2 1
2 3
3 1
3 2
The first k values are repeated n-k factorial times. Here is an easy, although inefficient, way to avoid the repetition:
int Factorial(int n)
{
int result = 1;
while (n>1) {
result *= n--;
}
return result;
}
void PermGenerator(int n, int k)
{
std::vector<int> d(n);
std::iota(d.begin(),d.end(),1);
cout << "These are the Possible Permutations: " << endl;
int repeat = Factorial(n-k);
do
{
for (int i = 0; i < k; i++)
{
cout << d[i] << " ";
}
cout << endl;
for (int i=1; i!=repeat; ++i)
{
next_permutation(d.begin(),d.end());
}
} while (next_permutation(d.begin(),d.end()));
}
However, there is an even easier and more efficient way to do it using std::reverse (from https://stackoverflow.com/a/2616837/951890)
void PermGenerator(int n, int k)
{
std::vector<int> d(n);
std::iota(d.begin(),d.end(),1);
cout << "These are the Possible Permutations: " << endl;
do
{
for (int i = 0; i < k; i++)
{
cout << d[i] << " ";
}
cout << endl;
std::reverse(d.begin()+k,d.end());
} while (next_permutation(d.begin(),d.end()));
}
The trick here is to realize that the last permutation is just the reverse of the first permutation, so by reversing the last n-k elements, you automatically skip to the last permutation of those elements.
You may use the following:
template <typename T>
void Combination(const std::vector<T>& v, std::size_t count)
{
assert(count <= v.size());
std::vector<bool> bitset(v.size() - count, 0);
bitset.resize(v.size(), 1);
do {
for (std::size_t i = 0; i != v.size(); ++i) {
if (bitset[i]) {
std::cout << v[i] << " ";
}
}
std::cout << std::endl;
} while (std::next_permutation(bitset.begin(), bitset.end()));
}
Live example
You output first k members of every n! permutations.
4! = 24 permutations. First two permutations are
1,2,3,4
1,2,4,3
and you have got 1,2 and 1,2
To get combinations (4,2), you might, for example, use vector
{0,0,1,1}
permute it, and output indexes of 1's
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
In my code n represents the number of blocks or no. of pyramids. This code prints only one pyramid , but I want to write a recursive function which would print the n number of pyramids by adding two elements in every successive pyramid.
For Example if n == 3
first pyramid
1 1 1
1
second pyramid
1 1 1 1 1
1 1 1
1
third pyramid
1 1 1 1 1 1 1
1 1 1 1 1
1 1 1
1
#include "pch.h"
#include <iostream>
//-------------------------------------------------------Function for Pyramid---------------------------------------------------------------
int f(int n)
{
int no_rows, no_columns;
no_columns = n;
no_rows = n - 1;
//-------------------------------------------------------Loop for the Pyramid---------------------------------------------------------------
for (int i = 1; i <= no_rows; i++)
{
for (int j = 0; j < no_columns; j++)
{
std::cout << "*";
}
std::cout << "\n";
no_columns = no_columns - 2;
for (int k = 0; k < i; k++)
{
std::cout << " ";
}
}
if (n == 0) return -1;
return f(n);
}
int main()
{
int n;
std::cout << "Please Enter the number of Blocks: ";
std::cin >> n;
//-------------------------------------------------------Printing the n blocks---------------------------------------------------------------
std::cout << f(n) << std::endl;
std::cout << f(n + 2) << std::endl;
std::cout << f(n + 4) << std::endl;
system("pasue");
}
I define the following routine to write a pyramid with a bottom length bl.
This works fine for you.
DEMO
void writePyramid(int bl)
{
for (int j = bl, j_space=0; j>0; j-=2, ++j_space)
{
for(int k=0; k< j_space; ++k){
std::cout << " ";
}
for (int l = 0; l<j; ++l){
std::cout << "*";
}
std::cout << "\n";
}
}
I am having some troubles with this problem presented from my lab. My goal is to produce an addition table that looks something like this -
(From range(1-5)) :
+ 1 2 3 4 5
1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7 8
4 5 6 7 8 9
5 6 7 8 9 10
Mine is looking like this, however :
+ 1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
My code looks like this :
if (choice == ADD) {
cout << "+";
for (int i = 0; i < max; i++) {
cout << "\t";
for (int j = min; j <= max; j++) {
cout << i + j << "\t";
}
}
}
(For reference, int max = maximum number in range, int min = minimum number in range, and choice is the decision for user to do either an addition or multiplication table). How can I change my code to fit the proper format? I can't seem to figure it out. Any hints/help would be greatly appreciated :)
#include <iostream>
using namespace std;
int main(){
int max = 5;
int min = 1;
if (true){
cout << "+\t";//print out the initial +
for(int i = min; i <= max; i++) cout << i << "\t";//print out the entire first row
cout << "\n"; //start the next row
//here is the main loop where you do most of the logic
for(int i = min; i <= max; i++){
cout << i << "\t"; //this prints out the first column of numbers
for(int j = min; j <=max; j++){
cout << j+i << "\t"; //this line fills in the body of your table
}
cout << "\n";//creates the space between each row
}
}
}
This code builds the table as explained:
for (int i = 0; i <= max; i++) {
if (i == 0)
cout << '+';
else
cout << i;
cout << '\t';
for (int j = min; j <= max; j++) {
cout << i + j << '\t';
}
cout << '\n';
}
Tip: when you want to print only a character, it is more efficient to use single quotes like '+' or '\t'. Double quotes are more expensive because they represent a const char*.
So I was learning about the stlibrary and graphs, and so I found out that graphs could be represented as a vector of lists which could be like this, where the 1 2 3 4 5 6 are the vertices, and from the vertice 1 I could go to the number 2, from the 3 to the 6, etc.
1 2 3 4 5 6
2 6 1 2
2
But, I already saved these values in the vector list, how could I loop through it to get the graph? My vector list is called _verticesEdges.
Like, to get an output like this:
Vertice 1: 2
Vertice 2:
Vertice 3: 6
Vertice 4: 1 2
Vertice 5:
Vertice 6: 2
Appreciate your help!
Assuming you have stored from index 1 to n (that means size of 0th index of your vector is zero), where n is number of vertices,
for (int i = 1; i <= n; i++)
{
cout << "Vertex " << i << ": ";
for (int j=0; j< _verticesEdges[i].size(); j++)
cout << _verticesEdges[i][j] << " ";
cout << "\n";
}
Something like this
std::vector<std::list<int>> vecOfLists;
// fill vecOfLists;
for (size_t i = 0; i < vecOfLists.size(); ++i) {
std::cout << "Vertice " << i + 1 << ": ";
for (int num : vecOfLists[i]) {
std::cout << num << " ";
}
std::cout << std::endl;
}
I am using usual for for iterating through lists, since index is required, and using range-based for for iterating through list, since this is better and modern way to iterate through whole container if you don't require indexes.
I was testing vector to vector initialization, I used range based for loop it gives different output.
with respect to Normal for loop.
vector<int> intVector;
for(int i = 0; i < 10; i++) {
intVector.push_back(i + 1);
cout << intVector[i] << endl;
}
cout << "anotherVector" << endl;
vector<int> anotherVector(intVector);
for(auto i : anotherVector)
cout << anotherVector[i] << endl;
//for(unsigned int i = 0; i < anotherVector.size(); i++) {
// cout << anotherVector[i] << endl;
//}
this range based for loop gives the output - Linux ubuntu
Output
STLTest Cunstructor Called.
1
2
3
4
5
6
7
8
9
10
anotherVector
2
3
4
5
6
7
8
9
10
81
2.
vector<int> intVector;
for(int i = 0; i < 10; i++) {
intVector.push_back(i + 1);
cout << intVector[i] << endl;
}
cout << "anotherVector" << endl;
vector<int> anotherVector(intVector);
//for(auto i : anotherVector)
// cout << anotherVector[i] << endl;
for(unsigned int i = 0; i < anotherVector.size(); i++) {
cout << anotherVector[i] << endl;
}
This gives different output.
output
STLTest Cunstructor Called.
1
2
3
4
5
6
7
8
9
10
anotherVector
1
2
3
4
5
6
7
8
9
10
why both for loop acting differently?
for(auto i : anotherVector)
cout << anotherVector[i] << endl;
This code doesn't do what you think it does. The range-based for loop iterates over values, not over indices. In other words, the loop variable (i) is assigned all ements of the vector in turn.
To replicate the functionality of your first loop, you need this:
for (auto i : anotherVector)
cout << i << endl;
What your original code was doing was take an element of the vector, and use it to index into the vector again. That's why the numbers were off by one (since the vector held number n + 1 at position n). Then, the final output (81 in your case) was effectively random and the result of Undefined Behaviour—you were reaching past the end of the vector.
i have some trouble while printing this pseudo-multidimensional array , with elements that are set already.
And the point of it is to swap the first and third row and 2nd and 4th column, but the output looks weird...
#include <iostream>
using namespace std;
int main()
{
int arr[12]= {
1,2,3,4,5,6,7,8,6,4,5,3
};
cout << "Before change: "<<endl;
for (int row=0;row<3;row++){
for (int col=0;col<4;col++){
cout << arr[row*col]<<" ";
}
cout <<endl;
}
cout << "After the row change: "<<endl;
for (int row=2;row>=0;row--){
for(int col=0;col<4;col++){
cout<<arr[row*col]<<" ";
}
cout<<endl;
}
cout << "After the column change: "<<endl;
int temp;
for(int row=0;row<3;row++){
temp=arr[row*1];
arr[row*1]=arr[row*3];
arr[row*3]=temp;
for (int col=0;col<4;col++){
cout<<arr[row*col]<<" ";
}
cout<<endl;
}
Instead of having an output like this:
1 2 3 4
5 6 7 8
6 4 5 3
6 4 5 3
5 6 7 8
1 2 3 4
6 3 5 4
5 8 7 6
1 4 3 2
i get this :
1 1 1 1
1 2 3 4
1 3 5 7
1 3 5 7
1 2 3 4
1 1 1 1
1 1 1 1
1 4 3 2
1 7 5 3
You wrong how to calculate the element inside the array arr[row*col] will be always 0 for the first row ( row = 0). So you have to do something like this:
#include <iostream>
using namespace std;
int main()
{
int arr[12] = {
1, 2, 3, 4, 5, 6, 7, 8, 6, 4, 5, 3
};
**int dimCol = 4;**
cout << "Before change: " << endl;
for (int row = 0; row < 3; row++){
for (int col = 0; col < 4; col++){
cout << arr[**(row*dimCol) + col**] << " ";
}
cout << endl;
}
cout << "After the row change: " << endl;
for (int row = 2; row >= 0; row--){
for (int col = 0; col < 4; col++){
cout << arr[**(row*dimCol) + col**] << " ";
}
cout << endl;
}
cout << "After the column change: " << endl;
int temp;
for (int row = 0; row < 3; row++){
temp = arr[row * 1];
arr[row * 1] = arr[row * 3];
arr[row * 3] = temp;
for (int col = 0; col < 4; col++){
cout << arr[**(row*dimCol) + col**] << " ";
}
cout << endl;
}
}
The formule will be: array[row*numberOfColumn + Column]
You got a wrong argument definition:
Instead of
array[row*col]
write this
array[row*4 + col]
So the formula is:
array[row*total_col + col]
The loop you are using multiplies each time your variable with Zero that's why you are getting 1 at the beginning of every line as your first element is 1, and arr[0] is 1.
*and your line 1 is
1 1 1 1*
because value of outer loop is zero and any value of variable of inner loop multiplied will result in 0.
the reason you are not getting correct output is your logic to print all element is not correct.
go for
array[row*4 + col]