I have problem with assignment, we need to implement recursive permutation in c++ for numbers.
Here is the code which is partly working, but missing some numbers.
I can't find where the problem is.
This code does work, but not exactly the right way.
This code take and array of number with size of that array.
in this case I am trying to solve the problem which appears when I send array longer than 3 numbers. If I send 3 numbers, output is:
///
1 2 3 /
1 3 2 /
3 1 2 /
2 1 3 /
2 3 1 /
3 2 1 /
Output in this case is correct. But when I set array to 4 and send size of it 4 I get:
///
1 2 3 4 /
1 2 4 3 /
1 4 2 3 /
4 1 2 3 /
**2 1 3 /
2 3 1 /
3 2 1 /**
3 2 1 4 /
3 2 4 1 /
3 4 2 1 /
4 3 2 1 /
Output is partly correct, but some numbers are missing.
Program should give output of all possible variations of numbers in array
#include <iostream>
using namespace std;
bool nextPermutation(int[],int);
void swap(int&, int&);
int Maxind(int[],int);
int Minind(int[],int);
void print (int[], int);
bool test (int[], int);
int fl=0;
int main() {
int a[]={1,2,3,4};
nextPermutation(a,4);
return 0;
}
void print(int a[], int s) {
for(int i=0; i<s; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
bool nextPermutation(int a[], int s)
{
int i=Maxind(a,s);
if(fl==0)
print(a,s);
if(i!=0) {
swap(a[i],a[i-1]);
nextPermutation(a,s);
}
else if(i==0 && test(a,s))
{
int p=a[0];
for(int i=0; i<=s-2; i++)
a[i]=a[i+1];
fl=1;
nextPermutation(a,s-1);
a[s-1]=p;
fl=0;
nextPermutation(a,s);
}
else
return false;
}
bool test (int a[], int s) {
if (Maxind(a,s)==0 && Minind(a,s)==s-1)
return false;
else
return true;
}
void swap(int& a, int& b)
{
int t=a; a=b; b=t;
}
int Maxind(int a[], int s)
{
int m=a[0], ind=0;
for(int i=0; i<s; i++)
if(m<a[i]) {
m=a[i];
ind=i;
}
return ind;
}
int Minind(int a[], int s)
{
int m=a[0], ind=0;
for(int i=0; i<s; i++)
if(m>a[i]) {
m=a[i];
ind=i;
}
return ind;
}
You need to send all numbers of possibilities for permutation.
If you change your main function you will get the solution. Add a loop in main funciton and send to nextPermutation(a, i) with variable i
int main() {
for(int i = 1; i < 5; i++) {
int a[]= {1,2,3,4};
nextPermutation(a,i);
}
return 0;
}
You should debug your program and also i figure out that your s value is decrasing here:
else if(i==0 && test(a,s)) {
int p=a[0];
for(int i=0; i<=s-2; i++) {
a[i]=a[i+1];
}
fl=1;
nextPermutation(a,s-1);
//*** careful you are decreasing s here and your output gives 3 numbers. !!***
a[s]=p;
fl=0;
nextPermutation(a,s);
}
I just modified the nextPermutation method of your code as follows and it worked.
bool nextPermutation(int a[], int s)
{
if(s == 0)
return false;
int i=Maxind(a,s);
if(fl==0)
print(a,s);
if(i!=0) {
swap(a[i],a[i-1]);
if(fl == 0)
nextPermutation(a,s);
else{
int temp = fl;
fl = 0;
nextPermutation(a,s+temp);
}
}
else if(i==0){
int p=a[0];
for(int i=0; i<=s-2; i++)
a[i]=a[i+1];
a[s-1]=p;
fl+=1;
nextPermutation(a,s-1);
}
else
return false;
}
Also I removed the methods test and Minind as they are not useful in my code.
Related
I have written an algorithm for creating the consecutive maximum list of an original list A, such that a(i+1)=max(a(i),a(i+1)).
OUT OF PLACE ALG:
void conMax(int A[], int maxA[],int n)
{
for (int i=0;i<n;i++)
{
if (A[i]>=A[i-1])
{
maxA[i]=A[i];
}
else
{
maxA[i]=A[i-1];
}
}
}
IN PLACE ALG:
void inConMax(int a[],int n)
{
int temp = -INFINITY;
for (int i=0;i<n;i++)
{
if(temp>a[i])
{
int k = temp;
temp = a[i];
a[i]=k;
}
else
{
temp=a[i];
}
}
}
Will using temporary variables within the loop to avoid using another array (maxA) stop my new alg from being in-place?
input: int a[9] = {7,5,9,23,24,6,4,19,20}
output: 7 7 9 23 24 24 6 19 20
The problem is to delete all the biggest number
for example:
cin: 1 2 3 4 5
cout: 1 2 3 4
cin: 5 1 2 3 5
cout: 1 2 3
cin: 5 5 1 2 5
cout: 1 2
cin: 5 5 5 1 5
cout: 1
and here is where things go wrong:
whenever my biggest number locate in the first and the last location with other location, the code print out the wrong result
please look at these example for better understanding:
cin: 5 5 1 2 5
expected cout: 1 2
but instead it cout: 5 1
cin: 5 5 1 5 5
expected cout: 1
but instead it cout: 5
I think the problem occured in the delete function but I can't figure out what went wrong no matter how many time i rechecked, i would be very happy if someone can help me solve this problem.
and sorry for my sloppy writing and bad english
here is my code:
#include <iostream>
using namespace std;
void Insert(int a[] ,int n)
{
for (int i=0; i<n; i++)
{
cout << "a[" << i << "]= ";
cin >> a[i];
}
}
void Delete(int a[], int n, int Biggestt)
{
int BiggestLocation;
for (int i=0; i<n-1; i++)
{
if (a[i]==Biggestt)
{
BiggestLocation=i;
}
}
for (int i=BiggestLocation; i<n-1; i++)
{
a[i]=a[i+1];
}
}
int Biggest(int a[],int n)
{
int Biggesttt=a[0];
for (int i=0; i<n; i++)
{
if (Biggesttt<a[i])
{
Biggesttt=a[i];
}
}
return Biggesttt;
}
void PrintOut(int a[],int n)
{
for (int i=0; i<n; i++)
{
cout << a[i] << " ";
}
}
int main()
{
int n,OriginalCount;
int Count=0;
cout << "Insert n: ";
cin >>n;
int a[100];
Insert(a,n);
int Biggestttt=Biggest(a,n);
for (int i=0; i<n-1; i++)
{
if(a[i]==Biggestttt)
{
Count++;
}
}
OriginalCount=Count;
while(Count!=0)
{
{
Delete(a,n,Biggestttt);
}
Count--;
}
if (a[n-1]==Biggestttt && OriginalCount==0)
{
PrintOut(a,n-1);
}
else if (a[n-1]!=Biggestttt && OriginalCount!=0)
{
PrintOut(a,n-OriginalCount);
}
else if (a[n-1]==Biggestttt && OriginalCount!=0)
{
PrintOut(a,n-OriginalCount-1);
}
return 0;
}
You are not far off. You biggest issues have to do with using void function () for all your functions. By using void as the type, you lose the ability to return valid (and needed) information.
For example in void Delete(int a[], int n, int Biggestt) the number of elements that remain in a[] will change as each element matching the Biggestt are removed from the array -- but you have no way of returning the final number of elements in the array after the removals take place. You can either change your return type from void to int and return an updated n, or you can pass n as a pointer parameter so when it is update within the function, its updated value is available back in the calling function when Delete() returns.
Additionally, your logic in main() is quite jumbled. You already have functions created to handle your needs, so main() should be relatively clean and have no more than a couple of variables to deal with. You could do something like:
int main (void)
{
int n, b,
a[MAXINT];
cout << "Insert n: ";
if (!(cin >> n)) { /* validate ALL user input */
cerr << "(invalid conversion or user canceled)\n";
return 1;
}
Insert (a, n); /* insert all array values */
cout << "original: "; /* output the original */
PrintOut (a, n);
b = Biggest (a, n); /* find the biggest number in the arry */
Delete (a, &n, b); /* delete all occurrences in array */
cout << "big deleted: "; /* output array with biggest removed */
PrintOut (a, n);
return 0;
}
(note: since your Delete() function has been left void a pointer to n was passed as a parameter so the final value of n after element deletion will be available back in the calling function (main() here))
Putting it altogether and making adjustments to the logic in Delete(), you could do something like the following:
#include <iostream>
using namespace std;
#define MAXINT 100
void Insert (int a[], int n)
{
for (int i=0; i<n; i++)
{
cout << "a[" << i << "]= ";
cin >> a[i];
}
}
void Delete(int *a, int *n, int Biggestt)
{
for (int i = 0; i < *n;)
{
if (*n > 1 && a[i] == Biggestt)
{
for (int j = i + 1; j < *n; j++)
a[j-1] = a[j];
(*n)--; /* if biggest removed, decrement n */
}
else
i++; /* only advance if biggest not removed at index */
}
}
int Biggest(int a[],int n)
{
int Biggesttt=a[0];
for (int i=1; i<n; i++)
{
if (Biggesttt<a[i])
{
Biggesttt=a[i];
}
}
return Biggesttt;
}
void PrintOut(int a[],int n)
{
for (int i=0; i<n; i++)
{
cout << " " << a[i];
}
cout << '\n';
}
int main (void)
{
int n, b,
a[MAXINT];
cout << "Insert n: ";
if (!(cin >> n)) { /* validate ALL user input */
cerr << "(invalid conversion or user canceled)\n";
return 1;
}
Insert (a, n); /* insert all array values */
cout << "original: "; /* output the original */
PrintOut (a, n);
b = Biggest (a, n); /* find the biggest number in the arry */
Delete (a, &n, b); /* delete all occurrences in array */
cout << "big deleted: "; /* output array with biggest removed */
PrintOut (a, n);
return 0;
}
Exmple Use/Output
$ ./bin/remove_biggest
Insert n: 5
a[0]= 5
a[1]= 1
a[2]= 2
a[3]= 3
a[4]= 5
original: 5 1 2 3 5
*n: 3
*n: 3
*n: 3
big deleted: 1 2 3
$ ./bin/remove_biggest
Insert n: 4
a[0]= 5
a[1]= 5
a[2]= 1
a[3]= 5
original: 5 5 1 5
*n: 1
big deleted: 1
What if all number in a[...] are the same? You have to be able to handle that case. The logic in Delete() now retains 1 number if the are all the same number. You may also choose to leave them ALL as there is no Biggestt. The are simultaneously the largest and smallest at the same time. How you handle it is up to you.
$ ./bin/remove_biggest
Insert n: 4
a[0]= 5
a[1]= 5
a[2]= 5
a[3]= 5
original: 5 5 5 5
*n: 1
big deleted: 5
If they were all the same Big number we just deleted all of them leaving 1 as it is also the minimum.
Using a Reference int& n Instead of a Pointer
In response to your comment and the suggestion by Fei Xiang, C++ allows you to pass a reference to n in Delete() instead of a pointer to ensure changes to n are visible back in the calling function (main here). The crux of the matter is when you simply pass a parameter to a function, the function receives a copy and any changes made to the variable within the function are lost on return. C++ provides a reference (e.g. int& n) which essentially passes an alias to the original and any changes made to the reference are changes made to the original. This is a refinement over passing the address of the variable because it does avoid having to dereference the pointer.
Using a reference, Delete() could be re-written as follows:
void Delete (int *a, int& n, int Biggestt)
{
for (int i = 0; i < n;)
{
if (n > 1 && a[i] == Biggestt)
{
for (int j = i + 1; j < n; j++)
a[j-1] = a[j];
n--; /* if biggest removed, decrement n */
}
else
i++; /* only advance if biggest not removed at index */
}
}
The call to Delete() in main() would be:
Delete (a, n, b); /* delete all occurrences in array */
And you have gotten rid of the so-called '*' marks :) (that Fei)
#include <iostream>
using namespace std;
void Insert(int a[] ,int n)
{
for (int i=0; i<n; i++)
{
cout << "a[" << i << "]= ";
cin >> a[i];
}
}
void Delete(int a[], int n, int Biggestt)
{
int BiggestLocation;
for (int i=0; i<n-1; i++)
{
if (a[i]==Biggestt)
{
a[i]=-1;
}
}
for (int i=1; i<n; i++)
{
if(a[i-1]==-1)
a[i-1]=a[i];
}
}
int Biggest(int a[],int n)
{
int Biggesttt=a[0];
for (int i=0; i<n; i++)
{
if (Biggesttt<a[i])
{
Biggesttt=a[i];
}
}
return Biggesttt;
}
void PrintOut(int a[],int n)
{
for (int i=0; i<n; i++)
{
cout << a[i] << " ";
}
}
int main()
{
int n,OriginalCount;
int Count=0;
cout << "Insert n: ";
cin >>n;
int a[100];
Insert(a,n);
int Biggestttt=Biggest(a,n);
for (int i=0; i<n-1; i++)
{
if(a[i]==Biggestttt)
{
Count++;
}
}
OriginalCount=Count;
while(Count!=0)
{
{
Delete(a,n,Biggestttt);
}
Count--;
}
if (a[n-1]==Biggestttt && OriginalCount==0)
{
PrintOut(a,n-1);
}
else if (a[n-1]!=Biggestttt && OriginalCount!=0)
{
PrintOut(a,n-OriginalCount);
}
else if (a[n-1]==Biggestttt && OriginalCount!=0)
{
PrintOut(a,n-OriginalCount-1);
}
return 0;
}
TRY THIS CODE.
Just equate all the instances of biggest number to -1 and later overwrite them with the neighboring elements which are not equal to -1.
The following is my code-
#include<iostream>
#include<cstdlib>
using namespace std;
void MergeSort(int*,int,int);
void Merge(int*,int*,int*,int,int,int);
int main()
{
int a[10];
for(int i=0;i<10;i++)
cin>>a[i];
cout<<"The unsorted array is : ";
for(int i=0;i<10;i++)
cout<<a[i]<<" ";
MergeSort(a,0,10);
cout<<"\n\n The Sorted array is : ";
for(int i=0;i<10;i++)
cout<<a[i]<<" ";
return 0;
}
void MergeSort(int *a,int l,int h)
{
int m = (l+h)/2;
int l1 = m-l;
int h1 = h-m;
int *lp = (int*)malloc(l1*sizeof(int));
int *rp = (int*)malloc(h1*sizeof(int));
for(int i=l,j=0;i<m;i++,j++)
{
lp[j] = a[i];
}
for(int i=m,j=0;i<h;i++,j++)
{
rp[j] = a[i];
}
if(l1 != 1)
MergeSort(lp,l,m);
if(h1 != 1)
MergeSort(rp,m,h);
Merge(lp,rp,a,l1,h1,(h-l));
}
void Merge(int *lp,int *rp,int *a,int l1,int h1,int b)
{
int i,j,k;
i=j=k=0;
while(i<l1 && j<h1)
{
if(lp[i] <= rp[j])
{
a[k] = lp[i];
i++;
}
else if(lp[i] > rp[j])
{
a[k] = rp[j];
j++;
}
k++;
}
while(i<l1)
{
a[k] = lp[i];
i++;k++;
}
while(j<h1)
{
a[k] = rp[j];
j++;k++;
}
}
for a given input like 1 5 2 4 3 6 7 9 8 7
output is - 0 0 1 3 5 and then some large numbers like 46977154 etc.
I can't figure out the problem in my code.
I found the error:
MergeSort(rp,m,h)
This should be
MergeSort(rp,l,h-m)
The rest is correct.
I try to generate all permutations with repetition of a number array by putting bound on summation of values.
Example;
I have my array {3,4,5,6} and my bound is 11.
I would like to generate all repetitive permutations reaching and just crossing 11 as:
3 3 3 3 //
3 4 3 3 //
3 3 5 3 //
3 3 3 6 //
3 4 4 3 //
4 4 4 //
6 6 //
6 4 3 //
5 5 5 //
..
So the cardinalty doesnt need to be the same as what we have with array.
Thanks for help in advance
I tried the following conversion from Java code, I got it, but still C++ gave the error "Unhandled exception":
void permute(int array[], int start[]){
int sum=0;
for (int i=0; i< sizeof(start)/sizeof(start[0]); i++) {
sum+= start[i];
}
if (sum >= 11) {
for (int n=0; n< sizeof(start) / sizeof(start[0]); n++)
cout << start[n] << " ";
cout << "\n";
return;
}
for (int i= 0; i < sizeof(array) / sizeof(array[0]) ; i++) {
int* newStart = new int[sizeof(start) / sizeof(start[0]) + 1];
memcpy (newStart, start, sizeof(start) / sizeof(start[0]) + 1);
newStart[sizeof(start) / sizeof(start[0])] = array[i];
permute(array, newStart);
}
}
void main ()
{
int array[] = {3,4,5,6};
int newarray[1];
for (int i=0; i< sizeof(array)/sizeof(array[0]); i++) {
newarray[0]=array[i];
permute(array, newarray);
}
system("pause");}
Additionally I would like to keep the indice numbers of all permutations and positions of each member. Example:
Permutation[1119] = [ 3 3 5 3],
Member[1119][1] = 3,
Member[1119][2] = 3 etc.
This is not so complicated. Because you're so vague about your language requirements, I took the freedom to invent my own pseudocode:
function generate(int[] array, int bound, int[] solution, int sum)
if (sum > bound)
print solution
else
for each elt in array
generate(array, bound, solution ++ [elt], sum + elt)
And call this as
generate([3, 4, 5, 6], 11, [], 0)
This is code for Java:
private static boolean checkConstraint(int[] array) {
int sum=0;
for (int i=0; i<array.length; i++) {
sum+= array[i];
}
//we found it, print
if (sum >= 11) {
System.out.println(Arrays.toString(array));
return true;
}
return false;
}
public static void permute(int[] array, int[] start){
if (checkConstraint(start)) {
return;
}
for (int i= 0; i < array.length; i++) {
int[] newStart= Arrays.copyOf(start, start.length + 1);
newStart[start.length] = array[i];
permute(array, newStart);
}
}
public static void main(String[] args) {
int[] array= {3,4,5,6};
for (int i=0; i<array.length; i++) {
permute(array, new int[] {array[i]});
}
}
How can I loop through all combinations of n playing cards in a standard deck of 52 cards?
You need all combinations of n items from a set of N items (in your case, N == 52, but I'll keep the answer generic).
Each combination can be represented as an array of item indexes, size_t item[n], such that:
0 <= item[i] < N
item[i] < item[i+1], so that each combination is a unique subset.
Start with item[i] = i. Then to iterate to the next combination:
If the final index can be incremented (i.e. item[n-1] < N-1), then do that.
Otherwise, work backwards until you find an index that can be incremented, and still leave room for all the following indexes (i.e. item[n-i] < N-i). Increment that, then reset all the following indexes to the smallest possible values.
If you can't find any index that you can increment (i.e. item[0] == N-n), then you're done.
In code, it might look something vaguely like this (untested):
void first_combination(size_t item[], size_t n)
{
for (size_t i = 0; i < n; ++i) {
item[i] = i;
}
}
bool next_combination(size_t item[], size_t n, size_t N)
{
for (size_t i = 1; i <= n; ++i) {
if (item[n-i] < N-i) {
++item[n-i];
for (size_t j = n-i+1; j < n; ++j) {
item[j] = item[j-1] + 1;
}
return true;
}
}
return false;
}
It might be nice to make it more generic, and to look more like std::next_permutation, but that's the general idea.
This combinations iterator class is derived from the previous answers posted here.
I did some benchmarks and it is a least 3x faster than any next_combination() function you would have used before.
I wrote the code in MetaTrader mql4 to do testing of triangular arbitrage trading in forex. I think you can port it easily to Java or C++.
class CombinationsIterator
{
private:
int input_array[];
int index_array[];
int m_indices; // K
int m_elements; // N
public:
CombinationsIterator(int &src_data[], int k)
{
m_indices = k;
m_elements = ArraySize(src_data);
ArrayCopy(input_array, src_data);
ArrayResize(index_array, m_indices);
// create initial combination (0..k-1)
for (int i = 0; i < m_indices; i++)
{
index_array[i] = i;
}
}
// https://stackoverflow.com/questions/5076695
// bool next_combination(int &item[], int k, int N)
bool advance()
{
int N = m_elements;
for (int i = m_indices - 1; i >= 0; --i)
{
if (index_array[i] < --N)
{
++index_array[i];
for (int j = i + 1; j < m_indices; ++j)
{
index_array[j] = index_array[j - 1] + 1;
}
return true;
}
}
return false;
}
void get(int &items[])
{
// fill items[] from input array
for (int i = 0; i < m_indices; i++)
{
items[i] = input_array[index_array[i]];
}
}
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
// driver program to test above class
#define N 5
#define K 3
void OnStart()
{
int x[N] = {1, 2, 3, 4, 5};
CombinationsIterator comboIt(x, K);
int items[K];
do
{
comboIt.get(items);
printf("%s", ArrayToString(items));
} while (comboIt.advance());
}
Output:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
#include <iostream>
#include <vector>
using namespace std;
class CombinationsIndexArray {
vector<int> index_array;
int last_index;
public:
CombinationsIndexArray(int number_of_things_to_choose_from, int number_of_things_to_choose_in_one_combination) {
last_index = number_of_things_to_choose_from - 1;
for (int i = 0; i < number_of_things_to_choose_in_one_combination; i++) {
index_array.push_back(i);
}
}
int operator[](int i) {
return index_array[i];
}
int size() {
return index_array.size();
}
bool advance() {
int i = index_array.size() - 1;
if (index_array[i] < last_index) {
index_array[i]++;
return true;
} else {
while (i > 0 && index_array[i-1] == index_array[i]-1) {
i--;
}
if (i == 0) {
return false;
} else {
index_array[i-1]++;
while (i < index_array.size()) {
index_array[i] = index_array[i-1]+1;
i++;
}
return true;
}
}
}
};
int main() {
vector<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
a.push_back(4);
a.push_back(5);
int k = 3;
CombinationsIndexArray combos(a.size(), k);
do {
for (int i = 0; i < combos.size(); i++) {
cout << a[combos[i]] << " ";
}
cout << "\n";
} while (combos.advance());
return 0;
}
Output:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
I see this problem is essentially the same as the power set problem. Please see Problems with writing powerset code to get an elegant solution.