Related
I want to divide an array into multiple(or one, maybe zero) arrays like the example below:
array = [0 1 1 2 3 4 0 3 0 3 3 0 5 6 7] -> array1 = [1 1 2 3 4] array2 = [3] array3 = [3 3] array4 = [5 6 7]
my naive approach to do this was first removing zeros from left and right then proceed to use two iterators to find the begin and end of every subarray and by using a vector constructor build the subarrays and pass them to a function. But I know for a fact that my approach is naive and inefficient so I would appreciate some suggestions on how to approach this more efficiently.
Thanks a lot guys!
also this is my code for my approach(a is the mother array):
for(int i = 0; i < a.size(); i++){
if(a[i] != 0)
break;
a.erase(a.begin() + i);
}
for(int i = a.size() - 1; i >= 0; i--){
if(a[i] != 0)
break;
a.erase(a.begin() + i);
}
auto begin = a.begin();
auto end = a.begin() + 1;
for (int i = 0; i < a.size(); i++){
if(a[i] == 0){
vector<int> temp(begin, end);
color(temp);
begin = end + 1;
end = begin + 1;
}
else end++;
}
One of the approach to solve this problem is to create an auxiliary array which contains index of all zero elements (in implementation const_iterator is used rather than index). This problem can be solved without creating such auxiliary array but the advantage of it is, you can find number of sub arrays are going to be created in advance. Approach is as follows,
Iterate input array and put index of zero elements in auxiliary array,
InputArray = [0, 1, 1, 2, 3, 4, 0, 3, 0, 3, 3, 0, 5, 6, 7]
Array contains zero elements index = [0, 6, 8, 11]
As you an see above there are four divider (zero index entries) which divides input array into 3 sub arrays and last zero is at index 11 and that is not last element of input array that's why one more sub array will be create so total sub arrays = 4 and for other details please see code,
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
using std::cout;
std::vector<std::vector<int>> splitAtZero(const std::vector<int>& arr){
std::vector<std::vector<int>::const_iterator> divider;
divider.reserve(std::max<std::size_t>(arr.size() / 4, 2));
for(std::vector<int>::const_iterator it = arr.cbegin(), endIt = arr.cend(); endIt != it; ++it){
if(0 == *it){
divider.push_back(it);
}
}
if(divider.empty()){
return {arr};
}
if(arr.size() == divider.size()){
return {};
}
std::size_t numOfSubArray = (divider.size() - 1) + (arr.cbegin() != divider.front() ? 1 : 0) +
(arr.cend() != divider.back() ? 1 : 0);
std::vector<std::vector<int>> subArr;
subArr.reserve(numOfSubArray);
std::vector<int>::const_iterator it = arr.cbegin();
for(std::vector<int>::const_iterator divderIt : divider){
if(divderIt - it > 0){
subArr.emplace_back(it, divderIt);
}
it = divderIt + 1;
}
if(arr.cend() != it){
subArr.emplace_back(it, arr.cend());
}
return subArr;
}
int main(){
std::string comma("");
for(std::vector<int>& subArr : splitAtZero({0, 1, 1, 2, 3, 4, 0, 3, 0, 3, 3, 0, 5, 6, 7})){
cout<< comma<< "[";
std::copy(subArr.cbegin(), subArr.cbegin() + (subArr.size() - 1), std::ostream_iterator<int>(cout, ", "));
cout<< subArr.back()<< "]";
comma = ", ";
}
cout<< '\n';
}
Output:
[1, 1, 2, 3, 4], [3], [3, 3], [5, 6, 7]
In the following approach that I propose you can retrieve the sub-arrays with a single sequential scan, with no need to exclude zeros at the beginning or at the end:
std::vector<std::vector<int>> arrays;
std::vector<int> currentArray;
for (int i = 0; i < a.size; i++)
{
if (a[i] == 0 || i == a.size - 1)
{
if (currentArray.size() != 0)
{
arrays.push_back(currentArray);
currentArray.clear();
}
}
else
{
currentArray.push_back(a[i]);
}
}
I'm trying to figure out how I can use recursion to do n-level nested for loops.
For example, if n=3, there would be 3 'levels'
for(z=0;z<6;z++){
for(y=0;y<6;y++){
for(x=0;x<6;x++){
if (z+y+x==f){
//do something
}
}
}
}
and so on.
I can't seem to figure out how I would be able to place the if loop in the last for loop and how I can access the variables of previous for loops from the if statement. I know that the question of variable nested loops has been asked alot of times, and I have looked through all of them. But none seem to help me.
Could someone present an easy way of using recursion to achieve this, keeping in mind that I'm still a beginner in c++, to point me in the right direction?
The use case is as follows:
Write a program to input the number of dice m. The program will output the total number of possible cases, the number of possible cases for each possible n and the n with the highest probability. Note: only one input m is read in. n is computed by the program
Example if user enters m=2 then program should output
The total number of possible cases is 36.
The possibilities are
2 1
3 2
4 3
.
.
.
12 1
For efficiency, I've avoided recursion. Also, it doesn't use any specific c++ stuff - it will work fine on C as well.
We're trying to create N nested "for" loops.
Instead of using
for(int i = 0; i<max; i++)
for (int j = 0; j<max; j++)
...
I'll be replacing i, j, ... with an array: i[0], i[1], ..., i[n-1].
Here's my solution:
const int n = /*Insert N here: how many loops do you need?*/;
int i[n+1]; // if "n" is not known before hand, then this array will need to be created dynamically.
//Note: there is an extra element at the end of the array, in order to keep track of whether to exit the array.
for (int a=0; a<n+1; a++) {
i[a]=0;
}
int MAX = 79; //That's just an example, if all of the loops are identical: e.g. "for(int i=0; i<79; i++)". If the value of MAX changes for each loop, then make MAX an array instead: (new) int MAX [n]; MAX[0]=10; MAX[1]=20;...;MAX[n-1]=whatever.
int p = 0; //Used to increment all of the indicies correctly, at the end of each loop.
while (i[n]==0) {//Remember, you're only using indicies i[0], ..., i[n-1]. The (n+1)th index, i[n], is just to check whether to the nested loop stuff has finished.
//DO STUFF HERE. Pretend you're inside your nested for loops. The more usual i,j,k,... have been replaced here with i[0], i[1], ..., i[n-1].
//Now, after you've done your stuff, we need to increment all of the indicies correctly.
i[0]++;
// p = 0;//Commented out, because it's replaced by a more efficient alternative below.
while(i[p]==MAX) {//(or "MAX[p]" if each "for" loop is different. Note that from an English point of view, this is more like "if(i[p]==MAX". (Initially i[0]) If this is true, then i[p] is reset to 0, and i[p+1] is incremented.
i[p]=0;
i[++p]++; //increase p by 1, and increase the next (p+1)th index
if(i[p]!=MAX)
p=0;//Alternatively, "p=0" can be inserted above (currently commented-out). This one's more efficient though, since it only resets p when it actually needs to be reset!
}
}
There, that's all. Hopefully the comments make it clear what it's meant to be doing. I think it should be pretty efficient - almost as much as real nested for-loops. Most of the overhead is a one-off at the beginning, so this should be more efficient that using recursive functions etc
The basic structure of a recursive algorithm with multiple loops is as follows:
void recursiveLoops(vector<int>& indexes, const vector<int>& endPerIndex, int currentIndex) {
if (currentIndex == indexes.size()) {
// This is where the real logic goes.
// indexes[i] contain the value of the i-th index.
} else {
for (indexes[pos] = 0 ; indexes[pos] != endPerIndex[pos] ; indexes[pos]++) {
// Recurse for the next level
recursiveLoops(indexes, endPerIndex, pos+1);
}
}
}
The setup for calling recursiveLoops from the top level requires two vectors - one for the indexes, and one for the number of iterations at each level. The example below sets up three nested loops, iterating 5, 6, and 9 times at each level:
vector<int> indexes(3, 0);
vector<int> endPerIndex;
endPerIndex.push_back(5);
endPerIndex.push_back(6);
endPerIndex.push_back(9);
recursiveLoops(indexes, endPerIndex, 0);
Here's an example in plain old C++. First I make a vector of the ranges for each dimension called maxes. if the sum of all indices are 2 then I print did something.
In the example I loop z from 0 to 1, y from 0 to 2, x from 0 to 3
You can for sure make this more neat.
Here goes:
#include <iostream>
#include <vector>
using namespace std;
int f(){
return 2 ;
}
void inner(int depth,vector<int> & numbers,vector<int> & maxes){
if (depth>0){
for(int i=0;i<maxes[depth-1];i++){
numbers[depth-1]=i;
inner(depth-1, numbers,maxes) ;
}
}else{
// calculate sum of x,y,z:
cout << "values are ";
for(int i=0;i<numbers.size();i++){
cout <<numbers[i]<<" ";
}
int thesum(0);
for(int i=0;i<numbers.size();i++){
thesum+=numbers[i];
}
if (thesum==f()){
cout << "did something! ";
}
cout<<endl;
}
}
void donest(){
vector<int> numbers;
numbers.resize(3);
vector<int> maxes;
maxes.push_back(4);
maxes.push_back(3);
maxes.push_back(2);
inner(numbers.size(),numbers,maxes);
}
int main(){
donest();
}
result:
values are 0 0 0
values are 1 0 0
values are 2 0 0 did something!
values are 3 0 0
values are 0 1 0
values are 1 1 0 did something!
values are 2 1 0
values are 3 1 0
values are 0 2 0 did something!
values are 1 2 0
values are 2 2 0
values are 3 2 0
values are 0 0 1
values are 1 0 1 did something!
values are 2 0 1
values are 3 0 1
values are 0 1 1 did something!
values are 1 1 1
values are 2 1 1
values are 3 1 1
values are 0 2 1
values are 1 2 1
values are 2 2 1
values are 3 2 1
just count the depth for each recursion function, and count to f..
void myRecursiveFunc(int depth){
if(depth == f)
//do something
return;
else{
myRecursiveFunc(depth + 1);
}
}
if you really want you can use three different functions for x,y and z.
You are very vague about why you want this. For a starter a possible solution is to replace each for loop with a recursive function.
void recursiveX(int zVal, int yVal, int xVal)
{
if(zVal+yVal+xVal == f)...
if(xVal != 0)
recursiveX(zVal, yVal, xVal -1);
}
void recursiveY(int zVal, int yVal)
{
recursiveX(zVal, yVal, 6);
if(yVal != 0)
recursiveY(zVal, yVal-1);
}
void recursiveZ(int val)
{
recursiveY(val, 6);
if(val != 0)
recursiveZ(val-1);
}
...
recursiveZ(6);
And in the end you can merge this all into one function. Nevertheless using recursion just because it is possible is never a good Idea.
You could write it like this, but... I wouldn't. It's confusing code and doesn't give you any benefits. If you want it because your true use case has a high number of nested loops, consider just not doing that, instead; it's a serious design smell.
void nested_loop(const int levels, const int comparator, const int level = 0, const int accumulator = 0)
{
if (level < levels) {
for (int i = 0; i < 6; i++) {
nested_loop(levels, comparator, level + 1, accumulator + i);
}
}
else {
if (accumulator == comparator) { // your if (z+y+x==f)
//do something
}
}
}
int main() {
const int levels = 3;
const int f = 42;
nested_loop(levels, f);
}
Live demo.
Variable loop using while loop in "C".
Concept
Creating a 2-dimensional array (arr[level][2]) in which first element is starting, and second element is end.
x[3][2] = {{0, 10}, {5, 20}, {2, 60}};
Creating another array with starting elements.
y[3] = {0, 5, 2};
We created a second array, because during the loop we will change the first element of "x" array.
Code
#include <stdio.h>
int main(){
// bruteforce
int level = 10;
int start[10] = {0, 0, 0, 0};
int x[10][2] = {{0, 5}, {0, 5}, {0, 5}, {0, 5}};
for (int i = 1;i < level; ++i){
x[i][1] = x[i][1] + 1;
}
while(3>2){
// Your code here
//
printf("%d %d %d %d\n", x[0][0], x[1][0], x[2][0], x[3][0]);
// variable loop code
// ==== Not To Modify ====
int a = 0;
int b = 0;
for(int i = 0;i < level; ++i){
if (x[i][0] >= x[i][1])
{
if(i != level-1){
x[i][0] = start[i];
x[i+1][0] = x[i+1][0] + 1;
}else{
a = 1;
}
b = 1;
}else{
if(b == 0){
x[0][0] = x[0][0] + 1;
b = 1;
}
}
}
if(a == 1){
break;
}
}
return 0;
}
This is a late answer, but maybe it will help someone.
Here is my solution in c++ without recursive function.:
int n_loops{3}; //number of nested for loops
int loops_idx[n_loops]; //like i,j,k but in an array
for (int i = 0; i < n_loops; i++)
loops_idx[i]=0;
int max_idx[n_loops]{3,2,4}; // like in for(; i < counter ;), but the counters in an array
bool is_finished = false;
int debug_n_of_execution{0};
while (!is_finished)
{
for (; loops_idx[0]<max_idx[0]; loops_idx[0]++)
{
/*
some code with loops_idx array as i,j,k...
*/
++debug_n_of_execution;
for (int i = 0; i < n_loops; i++)
std::cout<<loops_idx[i]<<" ";
std::cout << "\n";
}
--loops_idx[0]; //to cancel last increment
//Here it will increment the last loop_idx which isn't equal to max_idx[i]-1
//eg. after first above for loop loops_idx will be (max-1, 0, 0)
//So it will be after this loop (0, 1, 0) and start from the beginning...
for (int i = 0; i < n_loops+1; i++) //+1 to know if all loops are finished
{
if (i == n_loops)
{is_finished= true; break;}
if(loops_idx[i]==max_idx[i]-1)
continue;
++loops_idx[i];
for (int j = 0; j < i; j++) //make any previous loop = 0
loops_idx[j]=0;
break;
}
}
//just to check
int debug_perfect_n_of_execution{max_idx[0]};
for (int i = 1; i < n_loops; i++)
debug_perfect_n_of_execution*= max_idx[i];
std::cout<<"Number of execution: "<<debug_n_of_execution<<" = "<<debug_perfect_n_of_execution;
assert(debug_n_of_execution==debug_perfect_n_of_execution);
std::cout << "\nTests Finished";
And here is the result:
0 0 0
1 0 0
2 0 0
0 1 0
1 1 0
2 1 0
0 0 1
1 0 1
2 0 1
0 1 1
1 1 1
2 1 1
0 0 2
1 0 2
2 0 2
0 1 2
1 1 2
2 1 2
0 0 3
1 0 3
2 0 3
0 1 3
1 1 3
2 1 3
Number of execution: 24 = 24
Tests Finished
I've been working on a brute force algorithm to generate all permutations of a given set. Eventually, I want to feed each of these permutations into a nxn matrix to test if it is a valid magic square or not.
--I KNOW THAT THERE IS A WAY TO GENERATE A MAGIC SQUARE EASILY--
That is not what I want to do, though. I'm focusing on the brute force aspect of it.
For a set of 3 elements, it works wonderfully. However, once I use 4 or more elements, I lose out on a few permutations. Just from looking at the output of 4, I am missing 7 permutations.
#include <stdio.h>
#include <iostream>
using namespace std;
//ms = magic square
//n = size
void perm(int ms[], int n) {
int pivot = 0;
int index = 0;
int pivBit = 1;
int fin = 0;
int hold = 0;
//While we are not finished
while (fin == 0) {
//Incriment the index
++index;
if (index >= n) {
index = 0;
}
//if index is equal to the pivot
if (index == pivot) {
//Is this the first time visiting the pivot?
if (pivBit == 0) {
//Are we at the beginning again?
if (index == 0 && pivot == 0)
{
fin = 1;
}
pivBit = 1;
++index;
}
//Second time visiting?
else {
pivBit = 0;
++pivot;
if (pivot >= n) {
pivot = 0;
}
}
}
//If we are out of bounds
if (index >= n) {
index = 0;
}
//swap
hold = ms[index];
ms[index] = ms[pivot];
ms[pivot] = hold;
for (int i = 0; i < n; ++i) {
cout << ms[i];
if (i < n - 1) {
cout << ", ";
}
else {
cout << endl;
}
}
}
}
int main() {
cout << "Are you ready to brute force, my brother?" << endl;
//Set
int magicsquare[] = { 1, 2, 3, 4};
int size = 4;
perm(magicsquare, size);
getchar();
return 0;
}
My output is:
2 1 3 4
3 1 2 4
4 1 2 3
1 4 2 3
1 2 4 3
1 3 4 2
3 1 4 2
3 4 1 2
3 4 2 1
2 4 3 1
2 3 4 1
2 3 1 4
4 3 1 2
4 2 1 3
4 2 3 1
1 2 3 4
2 1 3 4
Looking at it, I can already see that I am missing both 1 4 3 2 and 1 3 2 4.
Where've I gone wrong in my algorithm?
The wiki article on permutation includes a common algorithm used to produce all permutations in lexicographic order, starting with an array of sequentially increasing integers, ending with that array reversed. wiki next permutation.
If dealing with an array of objects, you can generate an array of indices 0 through n-1 and use next permutation on the indices to produce all permutations of the array of objects.
You can also do a web search for next permutation to find similar algorithms. The recursive ones produce all permutations, but not in lexicographic order.
The simplest way to generate all permutations is recursive. For each i, swap the i'th element to the 0 position. Then recursively find all permutations of of the remaining array.
int buf[1000], n; // better to wrap these in a class...
void permute(int *a, int a_len) {
if (a_len == 1) {
for (int i = 0; i < n; i++) printf("%d ", buf[i]);
printf("\n");
} else {
for (int i = 0; i < a_len; i++) {
swap(a, 0, i);
permute(a + 1, a_len - 1);
swap(a, 0, i);
}
}
}
void run(int buf_len) {
for (int i = 0; i < buf_len; i++) buf[i] = i + 1;
n = buf_len;
permute(buf, buf_len);
}
This assumes no repeated elements in the original array. It's not to hard to have it take repeated elements into account.
I’m trying to write code that generate all subsets from set with one condition like
If I have threshold =2, and three set:
1, 2, 3, 4, 5
1,3,5
1,3,4
Then the program will output:
The generating set at the first iteration:
1 = number of frequency = 3
2 = number of frequency = 1
3 = number of frequency = 3
4 = number of frequency = 2
5= number of frequency = 2
Since the frequency of number 2 < threshold, I will exclude this set form any further superset,
The generating set at the second iteration:
1,3 = number of frequency = 3
1,4 = number of frequency = 2
1,5 = number of frequency = 2
3,4 = number of frequency = 2
3,5= number of frequency = 2
4,5= number of frequency = 1
Since the frequency of number (4,5) < threshold, I will exclude this set form any further superset,
The generating set at the third iteration
1,3,4= number of frequency = 2
1,3,5= number of frequency = 2
The generating set at the fourth iteration
No more superset because (4,5) < threshold we can’t generate (1,3,4,5)
I wrote the program, and I already generate all the subset, but Failed in two things:
I couldn't search in the map std::map <int,std::pair<list<int>,
int>> CandList to count the similar set (number of frequency)
I couldn't figure out how to apply the condition
Please I appreciate any help.
This my code:
int threshold = 2;
std::vector<std::list<int>> data;
std::map<int, int> FISupp;
typedef std::pair<list<int>, int> combo;
std::map <int,combo> CandList;
std::list<int> FrqList;
/*
input:Threshold =2, and data=
1 2 3 4 5
1 3 4 5
1 2 3 5
1 3
at first scan after PassOne function:
FISupp(1,4)
FISupp(2,2)
FISupp(3,4)
FISupp(4,4)
FISupp(5,3)
at k scan after Passk function:
---
*/
int Lsize = 2; // Level size
void ScanData()
{
ifstream in;
in.open("mydata.txt");
/* mydata.txt
1 2 3 4 5
1 3 4 5
1 2 3 5
1 3
*/
std::string line;
int i = 0;
while (std::getline(in, line))
{
std::stringstream Sline1(line);
std::stringstream ss(line);
std::list<int> inner;
int info;
while (ss >> info)
inner.push_back(info);
data.push_back(inner);
}
}
/* first pass to generate first Candidates items */
void PassOne()
{
for (unsigned i = 0; i < data.size(); ++i)
{
std::list<int>::iterator li;
for (li = data[i].begin(); li != data[i].end(); ++li)
FISupp[*li] += 1;
}
/*update the FFISupp by erasing all first Candidates items with support < Threshold*/
std::map<int, int> ::iterator current = FISupp.begin();
std::list<int> ls; /* save Candidates itemes with support < Threshold*/
while (current != FISupp.end())
{
if (current->second < threshold)
{
ls.push_back(current->first);
current = FISupp.erase(current);
}
else
++current;
}
/*update the the orginal data by erasing all first Candidates items with support < Threshold*/
for (unsigned i = 0; i < data.size(); ++i)
{
std::list<int>::iterator li;
std::list<int>::iterator item = ls.begin();
while (item != ls.end())
{
for (li = data[i].begin(); li != data[i].end(); ++li)
{
if (*li == *item)
{
li = data[i].erase(li);
break;
}
}
++item;
}
}
}
void FrequentItem(list<int> l, int indx)
{
int a = 0;
for (list<int>::iterator it = l.begin(); it != l.end(); ++it)
{
//std::list <int> &m2 = CandList[indx].first;
//auto itr = m2.find(*it);
//auto itr = std::find(CandList.begin(), CandList.end(), *it);
auto itr = CandList.find(*it);
if (itr != CandList.end())
{
a += CandList[indx].second;
CandList[indx].first.push_back(*it);
CandList[indx].second = a;
}
}
}
int ind = 0;
void Passk(int j, std::list<int>::iterator Itm , int q = 0)
{
if (Lsize == q)
{
FrequentItem(FrqList, ind);
++ind;
return;
}
else
{
for (std::list<int>::iterator Itm2 = Itm; Itm2 != data[j].end(); ++Itm2)
{
FrqList.push_back(*Itm2);
Passk(j, ++Itm2, q + 1);
FrqList.pop_back();
--Itm2;
}
}
}
void main(int argc, char *argv[])
{
int temp = 0;
int j = -1;
ScanData();
PassOne();
while (Lsize <= data.size()) // How to stop the loop when there is no more candidate >= threshold???
{
for (unsigned i = 0; i < data.size(); ++i)
{
std::list<int>::iterator items = data[i].begin();
Passk(++j, items);
}
j = -1;
++ Lsize;
}
data.clear();
system("PAUSE");
return;
}
Ok, I'll try for an answer. But first the assumptions:
You are working with ordered sets, i.e. the elements are strictly ascending.
You consider "normal" sets, i.e. no multi-sets where duplicate elements might appear.
Both assumptions might easily be relaxed, but I'll use this as base.
For this scenario, it might be more natural to encode your sets by bit-vectors (for instance using std::vector<bool> or boost::dynamic_bitset<>). In such a bit-vector, if the i-th element is set, it means that the number i is present in the set.
For example, your three sets are represented by this
1 1 1 1 1
1 0 1 0 1
1 0 1 1 0
Iteration 1: In your first iteration, you simply have to sum the elements, which is rather easy in this representation. One obtains
1 1 1 1 1
1 0 1 0 1
1 0 1 1 0
-----------
3 1 3 2 2
Next you discard all elements below your threshold, which simply amounts to setting the second row to zero:
1 0 1 1 1
1 0 1 0 1
1 0 1 1 0
Iteration K: Here, you count the occurence of all K-subsets, and discard them if their number is smaller than threshold. That is, formally, you generate the K-stencils
{ 1 1 0 0 0, 1 0 1 0 0, ... , 0 0 0 1 1} (for K=2)
{ 1 1 1 0 0, 1 1 0 1 0, ... , 0 0 1 1 1} (for K=3)
and so on. For each of these K-stencils, you count the occurence and eventually discard (note that K may also be one). So, you have three tasks, namely
Generation: is obtained by permutation of the initial bitvector {1 ... 1 0 ... 0}, where K elements are ordered to the left.
Counting: loop over the vectors of your set, and use bitwise and to check whether the current vector contains the stencil. For example: 1 0 1 1 1 & 0 0 0 1 1 == 0 0 0 1 1?.
Discarding: apply the inversed stencil via bitwise and (inversion is done via flip()). This will remove the relevant subsets. Finally discard any subset smaller than the number of iterations (e.g., in iteration 3, subset of size 2 are removed).
Here is an implemetation using primarily boost::dynamic_bitset<>, but std::vector<bool> for the permutations (that is because I didn't want to code a permutation by myself, but this can certainly be improved). Note that there are no maps or other more sophisticated storage schemes:
#include<vector>
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<boost/dynamic_bitset.hpp>
//only for nice output of a bitset
std::string screenOutput(const boost::dynamic_bitset<>& bits)
{
int n=bits.size();
std::string ret;
for(int i=n-1;i>=0;--i)
{
if(bits[i])
{
std::stringstream out;
out<<i+1<<" ";
ret=out.str()+ret;
}
}
return "{"+ret+"}";
}
//function implementing the actual logic
void removeSubsets(std::vector<boost::dynamic_bitset<> > ¤tSet, size_t K, size_t thresh)
{
size_t n=currentSet.front().size();
//create initial stencil {1 ... 1 0 ... 0}
std::vector<bool> stencil(n);
for(size_t i=0;i<K;++i)
stencil[i]=true;
//apply permutations to initial stencil
do
{
//generate dynamic_bitset from permuted vector<bool>
boost::dynamic_bitset<> temp(n);
for(size_t i=0;i<n;++i)
temp[i]=stencil[i];
//count the occurence of the stencil
size_t count=0;
for(size_t j=0;j<currentSet.size();++j)
{
if((currentSet[j] & temp) == temp)
++count;
}
//remove if at least one and less than thresh is found
if(count<thresh && count>0)
{
boost::dynamic_bitset<> tempFlip=temp;
tempFlip.flip();
for(size_t j=0;j<currentSet.size();++j)
{
//remove stencil from all bitset which contain it
if((currentSet[j] & temp) == temp)
currentSet[j]= (currentSet[j] & tempFlip);
}
}
}
while(std::prev_permutation(stencil.begin(),stencil.end()));
//further remove all supersets which contain less than K elements
for(size_t j=0;j<currentSet.size();++j)
if(currentSet[j].count()<K)
{
currentSet[j]=boost::dynamic_bitset<>(n,0);
}
}
The code can be used like this:
int main()
{
//initialize set of three bit-vectors (all elements to true)
std::vector<boost::dynamic_bitset<> > yourSet(3, boost::dynamic_bitset<>(5, (1<<5)-1) );
//set corresponding elements to false
yourSet[1][1]=false;
yourSet[1][3]=false;
yourSet[2][1]=false;
yourSet[2][4]=false;
std::cout<<"Original sets"<<std::endl;
for(size_t i=0;i<3;++i)
std::cout<<screenOutput(yourSet[i])<<std::endl;
std::cout<<std::endl;
removeSubsets(yourSet, 1, 2);
std::cout<<"After iteration 1:"<<std::endl;
for(size_t i=0;i<3;++i)
std::cout<<screenOutput(yourSet[i])<<std::endl;
std::cout<<std::endl;
removeSubsets(yourSet, 2, 2);
std::cout<<"After iteration 2:"<<std::endl;
for(size_t i=0;i<3;++i)
std::cout<<screenOutput(yourSet[i])<<std::endl;
std::cout<<std::endl;
removeSubsets(yourSet, 3, 2);
std::cout<<"After iteration 3:"<<std::endl;
for(size_t i=0;i<3;++i)
std::cout<<screenOutput(yourSet[i])<<std::endl;
std::cout<<std::endl;
}
It outputs:
Original set:
{1 2 3 4 5}
{1 3 5}
{1 3 4}
After iteration 1:
{1 3 4 5}
{1 3 5}
{1 3 4}
After iteration 2:
{}
{1 3 5}
{1 3 4}
After iteration 3:
{}
{}
{}
Man, I obviously have too much time.
EDIT: corrected code. Still you have to check whether it actually brings what you wanted.
I'm trying to figure out how I can use recursion to do n-level nested for loops.
For example, if n=3, there would be 3 'levels'
for(z=0;z<6;z++){
for(y=0;y<6;y++){
for(x=0;x<6;x++){
if (z+y+x==f){
//do something
}
}
}
}
and so on.
I can't seem to figure out how I would be able to place the if loop in the last for loop and how I can access the variables of previous for loops from the if statement. I know that the question of variable nested loops has been asked alot of times, and I have looked through all of them. But none seem to help me.
Could someone present an easy way of using recursion to achieve this, keeping in mind that I'm still a beginner in c++, to point me in the right direction?
The use case is as follows:
Write a program to input the number of dice m. The program will output the total number of possible cases, the number of possible cases for each possible n and the n with the highest probability. Note: only one input m is read in. n is computed by the program
Example if user enters m=2 then program should output
The total number of possible cases is 36.
The possibilities are
2 1
3 2
4 3
.
.
.
12 1
For efficiency, I've avoided recursion. Also, it doesn't use any specific c++ stuff - it will work fine on C as well.
We're trying to create N nested "for" loops.
Instead of using
for(int i = 0; i<max; i++)
for (int j = 0; j<max; j++)
...
I'll be replacing i, j, ... with an array: i[0], i[1], ..., i[n-1].
Here's my solution:
const int n = /*Insert N here: how many loops do you need?*/;
int i[n+1]; // if "n" is not known before hand, then this array will need to be created dynamically.
//Note: there is an extra element at the end of the array, in order to keep track of whether to exit the array.
for (int a=0; a<n+1; a++) {
i[a]=0;
}
int MAX = 79; //That's just an example, if all of the loops are identical: e.g. "for(int i=0; i<79; i++)". If the value of MAX changes for each loop, then make MAX an array instead: (new) int MAX [n]; MAX[0]=10; MAX[1]=20;...;MAX[n-1]=whatever.
int p = 0; //Used to increment all of the indicies correctly, at the end of each loop.
while (i[n]==0) {//Remember, you're only using indicies i[0], ..., i[n-1]. The (n+1)th index, i[n], is just to check whether to the nested loop stuff has finished.
//DO STUFF HERE. Pretend you're inside your nested for loops. The more usual i,j,k,... have been replaced here with i[0], i[1], ..., i[n-1].
//Now, after you've done your stuff, we need to increment all of the indicies correctly.
i[0]++;
// p = 0;//Commented out, because it's replaced by a more efficient alternative below.
while(i[p]==MAX) {//(or "MAX[p]" if each "for" loop is different. Note that from an English point of view, this is more like "if(i[p]==MAX". (Initially i[0]) If this is true, then i[p] is reset to 0, and i[p+1] is incremented.
i[p]=0;
i[++p]++; //increase p by 1, and increase the next (p+1)th index
if(i[p]!=MAX)
p=0;//Alternatively, "p=0" can be inserted above (currently commented-out). This one's more efficient though, since it only resets p when it actually needs to be reset!
}
}
There, that's all. Hopefully the comments make it clear what it's meant to be doing. I think it should be pretty efficient - almost as much as real nested for-loops. Most of the overhead is a one-off at the beginning, so this should be more efficient that using recursive functions etc
The basic structure of a recursive algorithm with multiple loops is as follows:
void recursiveLoops(vector<int>& indexes, const vector<int>& endPerIndex, int currentIndex) {
if (currentIndex == indexes.size()) {
// This is where the real logic goes.
// indexes[i] contain the value of the i-th index.
} else {
for (indexes[pos] = 0 ; indexes[pos] != endPerIndex[pos] ; indexes[pos]++) {
// Recurse for the next level
recursiveLoops(indexes, endPerIndex, pos+1);
}
}
}
The setup for calling recursiveLoops from the top level requires two vectors - one for the indexes, and one for the number of iterations at each level. The example below sets up three nested loops, iterating 5, 6, and 9 times at each level:
vector<int> indexes(3, 0);
vector<int> endPerIndex;
endPerIndex.push_back(5);
endPerIndex.push_back(6);
endPerIndex.push_back(9);
recursiveLoops(indexes, endPerIndex, 0);
Here's an example in plain old C++. First I make a vector of the ranges for each dimension called maxes. if the sum of all indices are 2 then I print did something.
In the example I loop z from 0 to 1, y from 0 to 2, x from 0 to 3
You can for sure make this more neat.
Here goes:
#include <iostream>
#include <vector>
using namespace std;
int f(){
return 2 ;
}
void inner(int depth,vector<int> & numbers,vector<int> & maxes){
if (depth>0){
for(int i=0;i<maxes[depth-1];i++){
numbers[depth-1]=i;
inner(depth-1, numbers,maxes) ;
}
}else{
// calculate sum of x,y,z:
cout << "values are ";
for(int i=0;i<numbers.size();i++){
cout <<numbers[i]<<" ";
}
int thesum(0);
for(int i=0;i<numbers.size();i++){
thesum+=numbers[i];
}
if (thesum==f()){
cout << "did something! ";
}
cout<<endl;
}
}
void donest(){
vector<int> numbers;
numbers.resize(3);
vector<int> maxes;
maxes.push_back(4);
maxes.push_back(3);
maxes.push_back(2);
inner(numbers.size(),numbers,maxes);
}
int main(){
donest();
}
result:
values are 0 0 0
values are 1 0 0
values are 2 0 0 did something!
values are 3 0 0
values are 0 1 0
values are 1 1 0 did something!
values are 2 1 0
values are 3 1 0
values are 0 2 0 did something!
values are 1 2 0
values are 2 2 0
values are 3 2 0
values are 0 0 1
values are 1 0 1 did something!
values are 2 0 1
values are 3 0 1
values are 0 1 1 did something!
values are 1 1 1
values are 2 1 1
values are 3 1 1
values are 0 2 1
values are 1 2 1
values are 2 2 1
values are 3 2 1
just count the depth for each recursion function, and count to f..
void myRecursiveFunc(int depth){
if(depth == f)
//do something
return;
else{
myRecursiveFunc(depth + 1);
}
}
if you really want you can use three different functions for x,y and z.
You are very vague about why you want this. For a starter a possible solution is to replace each for loop with a recursive function.
void recursiveX(int zVal, int yVal, int xVal)
{
if(zVal+yVal+xVal == f)...
if(xVal != 0)
recursiveX(zVal, yVal, xVal -1);
}
void recursiveY(int zVal, int yVal)
{
recursiveX(zVal, yVal, 6);
if(yVal != 0)
recursiveY(zVal, yVal-1);
}
void recursiveZ(int val)
{
recursiveY(val, 6);
if(val != 0)
recursiveZ(val-1);
}
...
recursiveZ(6);
And in the end you can merge this all into one function. Nevertheless using recursion just because it is possible is never a good Idea.
You could write it like this, but... I wouldn't. It's confusing code and doesn't give you any benefits. If you want it because your true use case has a high number of nested loops, consider just not doing that, instead; it's a serious design smell.
void nested_loop(const int levels, const int comparator, const int level = 0, const int accumulator = 0)
{
if (level < levels) {
for (int i = 0; i < 6; i++) {
nested_loop(levels, comparator, level + 1, accumulator + i);
}
}
else {
if (accumulator == comparator) { // your if (z+y+x==f)
//do something
}
}
}
int main() {
const int levels = 3;
const int f = 42;
nested_loop(levels, f);
}
Live demo.
Variable loop using while loop in "C".
Concept
Creating a 2-dimensional array (arr[level][2]) in which first element is starting, and second element is end.
x[3][2] = {{0, 10}, {5, 20}, {2, 60}};
Creating another array with starting elements.
y[3] = {0, 5, 2};
We created a second array, because during the loop we will change the first element of "x" array.
Code
#include <stdio.h>
int main(){
// bruteforce
int level = 10;
int start[10] = {0, 0, 0, 0};
int x[10][2] = {{0, 5}, {0, 5}, {0, 5}, {0, 5}};
for (int i = 1;i < level; ++i){
x[i][1] = x[i][1] + 1;
}
while(3>2){
// Your code here
//
printf("%d %d %d %d\n", x[0][0], x[1][0], x[2][0], x[3][0]);
// variable loop code
// ==== Not To Modify ====
int a = 0;
int b = 0;
for(int i = 0;i < level; ++i){
if (x[i][0] >= x[i][1])
{
if(i != level-1){
x[i][0] = start[i];
x[i+1][0] = x[i+1][0] + 1;
}else{
a = 1;
}
b = 1;
}else{
if(b == 0){
x[0][0] = x[0][0] + 1;
b = 1;
}
}
}
if(a == 1){
break;
}
}
return 0;
}
This is a late answer, but maybe it will help someone.
Here is my solution in c++ without recursive function.:
int n_loops{3}; //number of nested for loops
int loops_idx[n_loops]; //like i,j,k but in an array
for (int i = 0; i < n_loops; i++)
loops_idx[i]=0;
int max_idx[n_loops]{3,2,4}; // like in for(; i < counter ;), but the counters in an array
bool is_finished = false;
int debug_n_of_execution{0};
while (!is_finished)
{
for (; loops_idx[0]<max_idx[0]; loops_idx[0]++)
{
/*
some code with loops_idx array as i,j,k...
*/
++debug_n_of_execution;
for (int i = 0; i < n_loops; i++)
std::cout<<loops_idx[i]<<" ";
std::cout << "\n";
}
--loops_idx[0]; //to cancel last increment
//Here it will increment the last loop_idx which isn't equal to max_idx[i]-1
//eg. after first above for loop loops_idx will be (max-1, 0, 0)
//So it will be after this loop (0, 1, 0) and start from the beginning...
for (int i = 0; i < n_loops+1; i++) //+1 to know if all loops are finished
{
if (i == n_loops)
{is_finished= true; break;}
if(loops_idx[i]==max_idx[i]-1)
continue;
++loops_idx[i];
for (int j = 0; j < i; j++) //make any previous loop = 0
loops_idx[j]=0;
break;
}
}
//just to check
int debug_perfect_n_of_execution{max_idx[0]};
for (int i = 1; i < n_loops; i++)
debug_perfect_n_of_execution*= max_idx[i];
std::cout<<"Number of execution: "<<debug_n_of_execution<<" = "<<debug_perfect_n_of_execution;
assert(debug_n_of_execution==debug_perfect_n_of_execution);
std::cout << "\nTests Finished";
And here is the result:
0 0 0
1 0 0
2 0 0
0 1 0
1 1 0
2 1 0
0 0 1
1 0 1
2 0 1
0 1 1
1 1 1
2 1 1
0 0 2
1 0 2
2 0 2
0 1 2
1 1 2
2 1 2
0 0 3
1 0 3
2 0 3
0 1 3
1 1 3
2 1 3
Number of execution: 24 = 24
Tests Finished