I'm tried to figure out how to do it for quite of time and its not working as intended; I'm writing a code where there is 1 to k numbers, I need to find all possible combination without repeats. e.g. for 3: 1, 2, 3, 12, 13.
Example for counting 4-digits numbers with 1, 2, 3, 4, 5.
int k = 5;
for (int p = 0; p < k; p++)
{
for (int i = p+1; i < k; i++)
{
for (int j = i + 1; j < k; j++)
{
for (int h = j + 1; h < k; h++)
{
cout << p + 1 << i + 1 << j + 1 << h + 1 << endl;
}
}
}
}
And there is example for 3-digits number with 1, 2, 3.
int k = 4
for (int p = 0; p < k; p++)
{
for (int i = p+1; i < k; i++)
{
for (int j = i + 1; j < k; j++)
{
cout << p + 1 << i + 1 << j + 1 << endl;
}
}
}
I think that to count n-digits possible position without repeat i need n for's.
And i don't know how to do it without recursion which don't work when i do it.
My goal to get recursion which will count and print possible positions for n-digits.
I did recursion to count possibility myself, but love you guys for all your help.
My recursion is
void col(int ilosc)
{
static int st;
for (int i = st++; i < k; i++)
{
if (ilosc > 1)
col(ilosc - 1);
else
sposob++;
}
}
where ilosc is digits number and sposob is count of possible positions numbers.
NOTE: sposob and k is global variables.
I am not sure whether recursion is the best choice here, but you could do it like this:
typedef std::vector<int> IV;
IV getFirst(int k){
IV res;
for (int i=0;i<k-1;i++){res.push_back(i+1);}
return res;
}
bool getNext(IV& numbers,int i){
if (i==-1){return false;} // end of recursion
if (numbers[i]>i+1){return getNext(numbers,i-1);}
numbers[i]++;
return true;
}
bool getNext(IV& numbers){ // start of recursion
return getNext(numbers,numbers.size()-1);
}
int main() {
IV numbers = getFirst(5);
for (int i=0;i<numbers.size();i++){std::cout << numbers[i];}
std::cout << std::endl;
while(getNext(numbers)){
for (int i=0;i<numbers.size();i++){std::cout << numbers[i];}
std::cout << std::endl;
}
}
I think this will get you pretty close. I have an occasional repeat here, but this should set you on the right path.
const int max_depth = 5; // How long your string is
const int max_digit = 3; // Max digit you are counting to
int *nums = new int [max_depth];
void recurse_count(int depth)
{
if (depth < max_depth)
{
for(int i = depth; i <= depth+1; i++)
{
nums[depth] = i;
recurse_count(i+1);
}
}
else
{
for (int j = 0; j < max_depth; j++)
cout<<nums[j]+1;
cout<<endl;
}
}
int main()
{
recurse_count(0);
return 0;
}
My approach (still too early in the evening probably, I had problems with it)
namespace detail
{
void recurse_hlp(int min, int max, std::vector<int> vals, std::function<void(const std::vector<int>&)> f, std::size_t ptr)
{
if (ptr == vals.size())
f(vals);
else
{
for (int i = min; i <= max; ++i)
{
vals[ptr] = i;
recurse_hlp(min, max, vals, f, ptr + 1);
}
}
}
}
void recurse(int min, int max, int count, std::function<void(const std::vector<int>&)> f)
{
std::vector<int> vals(count);
detail::recurse_hlp(min, max, vals, f, 0);
}
void print(const std::vector<int>& vals)
{
for (int v : vals)
std::cout << v << " ";
std::cout << std::endl;
}
int main()
{
recurse(0, 5, 3, &print);
}
recurse gets a function accepting std::vector<int>, which contains all numbers from min to max up to count places.
Related
I'm new to C++ and I'm trying to implement a merge sort but when I print my array in my main method it remains unmodified and I'm unsure of why that's the case. I tried printing the contents of the arrays that I split but it gave me values that I was unsure of where it was coming from.
#include <iostream>
#include <vector>
using namespace std;
void merge(vector<int> left, vector<int> right, vector<int> arr) {
int j = 0;
int k = 0;
int l = 0;
while (j < left.size() && k < right.size()) {
if (left[j] >= right[k]) {
arr[l] = right[k];
k += 1;
l += 1;
} else {
arr[l] = left[j];
j += 1;
l += 1;
}
}
if (j < left.size()) {
for (int i = j + k; i < arr.size(); i++) {
j += 1;
arr[i] = left[j];
}
}
if (k < right.size()) {
for (int i = j + k; i < arr.size(); i++) {
k += 1;
arr[i] = right[k];
}
}
}
void merge_sort(vector<int> arr) {
int n = arr.size();
if (n <2) {
return;
}
int mid = n / 2;
vector<int> left = vector<int>(arr.begin(), arr.end() - mid - 1);
for (int i : left) {
cout << i << " ";
}
cout << "\n";
vector<int> right = vector<int>(arr.begin() + mid, arr.end());
for (int i : right) {
cout << i << " ";
}
cout << "\n";
merge_sort(left);
merge_sort(right);
merge(left, right, arr);
}
int main() {
vector<int> arr = {3, 3, 4, 6, 42, 6, 2};
merge_sort(arr);
for (int i : arr) {
cout << i << " ";
}
return 0;
}
You are creating a copy of the vector when you pass it to merge_sort. Any changes made to arr in the function will not be visible in main.
Instead, you need to pass the vector by reference if you want the function to modify the argument:
void merge_sort(vector<int> &arr) {
// ^ by reference
Similarly for merge:
void merge(vector<int> &left, vector<int> &right, vector<int> &arr) {
I have problem to solve and I'm stuck, I don't know how to start.
Suppose I have R childrens and S candies. I want to divide candies between childrens. Each child can get 0, 1, 2, 3 or 4 candies. How to find all the possibilities of such a division?
#include <iostream>
using namespace std;
void solve(int r, int s) {
if (s == 0)
{
cout << "no more candies" << endl;
return;
}
if (r == 0)
{
cout << "last child" << endl;
return;
}
for (int j = 0; j < 4 && j <= s; ++j)
{
cout << "r: " << r << " j: " << j << endl;
solve(r-1, s - j);
}
}
int main () {
int r, s;
cin >> r >> s;
solve(r, s);
return 0;
}
For now I have sth like this, I see in output that I have solutions here, but I don't know how to grab and store all possibilities into for example vector.
Just store counts and save variants at the last recursion level
vector<int> counts;
vector<vector<int>> sol;
void solve(int r, int s) {
if (s == 0)
{
sol.push_back(counts);
return;
}
if (r == 0)
{
return;
}
for (int j = 0; j <= 4 && j <= s; ++j)
{
counts[r - 1] += j;
solve(r - 1, s - j);
counts[r - 1] -= j;
}
}
int main() {
int r, s;
r = 3;
s = 5;
for (int j = 0; j < r; ++j)
counts.push_back(0);
solve(r, s);
for (int i = 0; i < sol.size(); i++) {
for (int j = 0; j < sol[i].size(); j++) {
cout << sol[i][j] << ' ';
}
cout << endl;
}
return 0;
}
I have a loop in each iterate an array is printed. now I need this array so I want to put them in a 2 dimension vector. I wrote this code but I dont know why it does not work!
when I run it does not print any thing and it dont show any error!
int main() {
int i, u;
const int j = 9;
vector<vector<int>> V;
int B[9] = {};
for (int r = 0; r<10; r++) {
B[r] = 1;
for (int t = 0; t<V.size(); t++) {
for (int w = 0; w<j; w++, u++) {
V[t][w] = B[u];
}
}
}
for (int m = 0; m<V.size(); m++) {
for (int k = 0; k<j; k++) {
cout << "V=" << " " << V[m][k];
}
}
return 0;
}
For example in the first loop in each iterate B changes and I want to store all of them in a matrix! for example I have:
first iterate: B=(1,0,0)
second iterate: B=(0,1,0)
third iterate: B=(0,0,1)
now I want to have:
V={{1,0,0},{0,1,0},{0,0,1}}
Let's say that you have N int[N] values, and you want 1 vector<vector<int>> value.
std::vector<int> fromArray(int (&B)[N])
{
return { std::begin(B), std::end(B) };
}
This is a function that will turn a 1D array into a 1D vector. you will need to call it N times.
std::vector<std::vector<int>> fromArrays(int (&Bs)[N][N])
{
std::vector<std::vector<int>> result{ N };
std::transform(std::begin(Bs), std::end(Bs), result.begin(), fromArray);
return result;
}
Here we take a 2D array and turn it into a 2D vector. This requires you have all the Bs together.
int main()
{
constexpr int N = 3;
std::vector<std::vector<int>> V;
for (int i = 0; i < N; ++i)
{
int B[N] = {};
B[i] = 1;
V.emplace_back(fromArray(B));
}
for (std::vector<int> & v : V)
{
for (int i : v)
{
std::cout << i << " ";
}
std::cout << "\n";
}
return 0;
}
Alternately, if you don't have all the Bs all in one go, just loop N times getting one B
If guessing, there is a my implementation:
int main() {
int len = 9;
int div = 3;
int total = len / div;
int B[len]={1, 0, 0, 0, 1, 0, 0, 0, 1};
vector<vector<int> > V(total);
int cnt = 0;
for (int i = 0; i < len && cnt < total; i += div) {
for (int j = i; j < i + div; j++) {
V[cnt].push_back(B[j]);
}cnt++;
}
for (int i = 0; i < total; i++) {
for (int j = 0; j < V[i].size(); j++) {
cout << V[i][j] << " ";
}cout << endl;
}
return 0;
}
V is like this:
1 0 0
0 1 0
0 0 1
You probably want this:
int main() {
const int Bsize = 9;
const int NumberOfLines = 4; // number of iterations
int B[Bsize] = { 1,2,3,4,5,6,7,8,9 };
vector<vector<int>> V;
V.resize(NumberOfLines);
int bIndex = 0;
for (int r = 0; r < NumberOfLines; r++) {
// add code that changes B here
V[r].resize(Bsize);
for (int w = 0; w < Bsize; w++) {
V[r][w] = B[w];
}
}
for (int m = 0; m < V.size(); m++) {
for (int k = 0; k < V[m].size(); k++) {
cout << " " << V[m][k];
}
cout << endl;
}
return 0;
}
In this sample we'll generate 4 lines (one for each iteration), but B is each time the same here. If you want B to change between each iteration, you need to insert the corresponding code that changes B.
The output of the sample will be:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
It currently terminates at j=5 and I want it to somehow skip j=5 iteration and continue till j<10.
for(int j=0; j!=5 && j<10 ; j++)
{
cout<<"loop working for j = "<<j<<endl;
}
for(int j = 0; j < 10; j++) {
if (j == 5)
continue;
std::cout << "loop working for j = " << j << std::endl;
}
Well, yet another version
for(auto j: std::initializer_list<int>{0, 1, 2, 3, 4, 6, 7, 8, 9}) {
}
for(int j=0; j<10 ; j++)
{
if(j != 5){
cout<<"loop working for j = "<<j<<endl;
}
}
For example you can write the following way
for ( int j = 0; j < 10 ; ++j )
{
if ( j != 5 ) cout << "loop working for j = " << j << endl;
}
or
for ( int j = 0; j < 10 ; j += ( j == 4 ) + 1 )
{
cout << "loop working for j = " << j << endl;
}
You could also increment the counter in a dedicated function. Here's an example with a lambda function:
#include <iostream>
int main()
{
auto const incrementSkippingFive = [](int& j)
{
if (j == 4)
{
j += 2;
}
else
{
++j;
}
};
for (int j = 0; j < 10; incrementSkippingFive(j))
{
std::cout << "loop working for j = " << j << "\n";
}
}
Of course c++ should always be written as expressively as possible:
int main()
{
for (auto i : everything.from(1).to(9).except(5))
{
std::cout << i << std::endl;
}
}
Of course this requires some trivial supporting code. This can go in a library:
#include <iostream>
#include <vector>
#include <algorithm>
struct range
{
range(int x, int y)
{
while (x < y) {
values.push_back(x++);
}
}
void remove(int z)
{
values.erase(std::remove(std::begin(values),
std::end(values), z),
std::end(values));
}
range except(int z) const {
auto result = *this;
result.remove(z);
return result;
}
auto begin() const {
return std::begin(values);
}
auto end() const {
return std::end(values);
}
std::vector<int> values;
};
struct from_clause
{
int x;
range to(int y) const { return range(x, y + 1); }
};
struct range_builder
{
from_clause from(int n) const { return from_clause{n}; }
};
constexpr range_builder everything {};
expected results:
1
2
3
4
6
7
8
9
Are you serious?
;-)
I've managed to find the minimum value of every row of my 2D array with this
void findLowest(int A[][Cm], int n, int m)
{
int min = A[0][0];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (A[i][j] < min)
{
min = A[i][j];
}
}
out << i << " row's lowest value " << min << endl;
}
}
I'am trying to find the maximum value of every row using the same way,but it only shows me first maximum value
void findHighest(int A[][Cm], int n, int m)
{
int max = A[0][0];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (A[i][j] > max)
{
max = A[i][j];
}
}
out << i << " row's highest value " << max << endl;
}
}
I can't find what's wrong with the second function and why is it only showing me the first maximum value it finds. Any help ?
Both functions return the result (maximum or minimum) for the whole array rather than each row, because you set max once rather than once per row. You can get the result for each row as follows:
void findHighest(int A[][Cm], int n, int m)
{
for (int i = 0; i < n; i++)
{
int max = A[i][0];
for (int j = 1; j < m; j++)
{
if (A[i][j] > max)
{
max = A[i][j];
}
}
// do something with max
}
}
or, even better, use the standard library function max_element:
void findHighest(int A[][Cm], int n, int m)
{
if (m <= 0) return;
for (int i = 0; i < n; i++)
{
int max = *std::max_element(A[i], A[i] + m);
// do something with max
}
}
This should give you all values which is easy to check:
#include <algorithm>
#include <iostream>
enum { Cm = 2 };
void findHighest(int A[][Cm], int n, int m) {
if (m <= 0) return;
for (int i = 0; i < n; i++) {
int max = *std::max_element(A[i], A[i] + m);
std::cout << max << " ";
}
}
int main() {
int A[2][2] = {{1, 2}, {3, 4}};
findHighest(A, 2, 2);
}
prints 2 4.
If your compiler supports C++11, for concrete arrays you could use the following alternative, that's based on std::minmax_element:
template<typename T, std::size_t N, std::size_t M>
void
minmax_row(T const (&arr)[N][M], T (&mincol)[N], T (&maxcol)[N]) {
for(int i(0); i < N; ++i) {
auto mnmx = std::minmax_element(std::begin(arr[i]), std::end(arr[i]));
if(mnmx.first != std::end(arr[i])) mincol[i] = *(mnmx.first);
if(mnmx.second != std::end(arr[i])) maxcol[i] = *(mnmx.second);
}
}
Live Demo
Your test data is guilty for not clearly showing you the defect.
The row minima occur in decreasing values, so that they get updated on every row.
And the row maxima also occur in decreasing values, so that the first one keeps winning.
As others pointed, your function finds the global minimum/maximum, no the per-row extrema.
Move the initialization of the min/max variable inside the outer loop.
As mentioned your code only shows the maximum element in the whole array.
Here is the code which will help you.
void findHighest(int A[][Cm], int n, int m)
{
int max[n];
max[0]=A[0][0];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (A[i][j] > max[i])
{
max[i] = A[i][j];
}
}
cout << i << " row's highest value " << max[i] << endl;
}
}
{
int i,j;
int arr[4][2]={(1,2),(3,4),(5,6),(7,8)};
int max;
max=arr[0][0];
for( int i=0; i<4; i++)
{
for(int j=0; j<2; j++)
{
if(max<arr[i][j])
{
max=arr[i][j];
}
}
}
int min;
min=arr[0][0];
for(int i=0; i<4; i++)
{
for(int j=0; j<2; j++)
{
if(min>arr[i][j])
{
min=arr[i][j];
}
}
}
cout<<"maximum number is:"<<max;
cout<<endl;
cout<<"Minimum Number is:"<<min;
}