wrap three nested for loops into recursion - c++

I have a method that returns all possible combinations of 3 elements in a given string.
void FindAllCombinationsBy3(string &str, int start)
{
for (int i = 0; i < str.length() - 2; i++)
{
for (int j = i + 1; j < str.length() - 1; j++)
{
for (int k = j + 1; k < str.length(); k++)
{
cout << str[i] << str[j] << str[k] << endl;
}
}
}
return;
}
It works fine and outputs this: abc abd abe abf acd ace acf ade. But I want to write a recursive version of the method that will receive a parameter n of combinations length. So not just 3, but a custom length. It should probably look something like this. But I just got lost with this recursion conditions.
void FindAllCombinationsByNValues(string &str, int start, int depth, int n)
{
if (depth++ >= n)
{
return;
}
for (int i = start; i < str.length() - n + depth; i++)
{
cout << str[i];
FindAllCombinationsByNValues(str, start + 1, depth, n);
}
cout << endl;
}
I know that this were asked a million times but other solution didn`t help yet.

void print_combinations(const std::string& s, unsigned n, unsigned j = 0, const std::string& a = "") {
if (n == 0) {
std::cout << a << std::endl;
} else {
for (auto i = j; i < s.length() - (n - 1); ++i) {
print_combinations(s, n - 1, i + 1, a + s[i]);
}
}
}
Usage:
print_combinations("abcde", 3);
Output:
abc
abd
abe
acd
ace
ade
bcd
bce
bde
cde

Related

How do this program but in reverse, pattern

so i want output like this
1
123
12345
123
1
i already make the program but it only output these, and im confused how to output the bottom triangle
1
123
12345
here's my program
#include <iostream>
using namespace std;
int main() {
int n = 3 ;
int i, j, k;
for (i = 1; i <= n; i++) {
for (j = n; j > i; j--) {
cout << " ";
}
for (k = 1; k <= (2 * i - 1); k++) {
cout << k;
}
cout <<endl;
}
return 0;
}
#Mojtaba's answer is a perffect extension to your approach.
However, I wanted to provide another method that is generally used in creating such strings that are formatted in a particular manner. It is common to create the entire pattern line by line and then print to the console all at once.
I have appropriately commented the code for your reference and it should be easy to understand:
#include <iostream>
#include <vector>
void pattern(int n) {
std::vector<std::string> lines; // store the first n lines to print later
int length = 2*n - 1; // length of each line
for(int i = 0; i < n; i++) {
std::string str = std::string(length, ' ');
for(int j = 1; j <= 2*i + 1; j++) {
str[n - i + j - 2] = j + '0';
// indexing can be figured by observing the pattern
}
lines.emplace_back(str);
}
for(int i = 0; i < n; i++) {
std::cout << lines[i] << std::endl;
}
for(int i = n-2; i >= 0; i--) {
std::cout << lines[i] << std::endl;
}
return;
}
int main() {
int n;
std::cin >> n;
pattern(n);
}
I added another for loop exactly like yours with different order from n-1. I modified your code to this:
int main() {
int n = 3 ;
int i, j, k;
for (i = 1; i <= n; i++) {
for (j = n; j > i; j--) {
cout << " ";
}
for (k = 1; k <= (2 * i - 1); k++) {
cout << k;
}
cout <<endl;
}
for (i = n - 1; i >= 1; i--) {
for (j = n; j > i; j--) {
cout << " ";
}
for (k = 1; k <= (2 * i - 1); k++) {
cout << k;
}
cout <<endl;
}
return 0;
}
Now it returns:
1
123
12345
123
1

Why the simple multiplication would result in some garbled characters?

I try to design a program that implements the multiplication between two big integers(Using C++). But after I complete it, I found that if I input the two integers by the command arguments, the results would be sometimes very weird and sometimes right. Please help me figure out the reason and tell me how to fix it. Thanks (The main function that implements the function of multiplication between two big integers is mul() ).
#include <iostream>
#include <cstring>
#include <stdlib.h>
using namespace std;
void mul(char *c1, char *c2, int len1, int len2);
void printArr(char *c1, char *c2, int len1, int len2);
int main(int argc, char **argv)
{
if (argv[1] != NULL)
{
char cArr1[500], cArr2[500];
for (int i = 0; i < strlen(argv[1]); i++)
{
cArr1[i] = argv[1][i];
}
for (int i = 0; i < strlen(argv[2]); i++)
{
cArr2[i] = argv[2][i];
}
int len1 = strlen(cArr1);
int len2 = strlen(cArr2);
printArr(cArr1, cArr2, len1, len2);
(len1 > len2) ? mul(cArr1, cArr2, len1, len2) : mul(cArr2, cArr1, len2, len1);
exit(100);
}
while (true)
{
cout << "Please input two integers" << endl;
char cArr1[500], cArr2[500];
cin >> cArr1;
if (cArr1[0] == 'q' && cArr1[1] == 'u' && cArr1[2] == 'i' && cArr1[3] == 't')
{
exit(1000);
}
cin >> cArr2;
int parity = 0;
int len1 = strlen(cArr1);
int len2 = strlen(cArr2);
printArr(cArr1, cArr2, len1, len2);
if (cArr1[0] == '-')
{
for (int i = 1; i < len1; i++)
{
cArr1[i - 1] = cArr1[i];
}
parity++;
len1--;
}
if (cArr2[0] == '-')
{
for (int i = 1; i < len2; i++)
{
cArr2[i - 1] = cArr2[i];
}
parity++;
len2--;
}
bool isDigit = true;
for (int i = 0; i < len1; i++)
{
if (!isdigit(cArr1[i]))
{
isDigit = false;
}
}
for (int i = 0; i < len2; i++)
{
if (!isdigit(cArr2[i]))
{
isDigit = false;
}
}
if (!isDigit)
{
cout << "\rInvalid input. Try again" << endl;
continue;
}
if (parity % 2 != 0)
{
cout << "-";
}
(len1 > len2) ? mul(cArr1, cArr2, len1, len2) : mul(cArr2, cArr1, len2, len1);
}
}
void mul(char *bigger, char *smaller, int bigLen, int smallLen)
{
int *bigNum = new int[bigLen];
int *smallNum = new int[smallLen];
for (int i = 0; i < bigLen; i++)
{
bigNum[i] = bigger[bigLen - i - 1] - '0';
}
for (int i = 0; i < smallLen; i++)
{
smallNum[i] = smaller[smallLen - i - 1] - '0';
}
int res[30];
for (int i = 0; i < 30; i++)
{
res[i] = 0;
}
for (int i = 0; i < smallLen; i++)
{
for (int j = 0; j < bigLen; j++)
{
res[i + j] += bigNum[j] * smallNum[i];
}
}
for (int i = 0; i < bigLen + smallLen; i++)
{
int digit = res[i] % 10;
int carry = res[i] / 10;
res[i] = digit;
res[i + 1] += carry;
}
bool null = false;
for (int i = bigLen + smallLen - 1; i >= 0; i--)
{
if (res[i] != 0 && res[i + 1] == 0)
{
null = true;
}
if (null)
{
cout << res[i];
}
}
cout << endl;
}
void printArr(char *c1, char *c2, int len1, int len2)
{
for (int i = 0; i < len1; i++)
{
cout << c1[i];
}
cout << " * ";
for (int i = 0; i < len2; i++)
{
cout << c2[i];
}
cout << " = ";
}
Just initialize your char arrays to empty ones:
char cArr1[500] = {};
char cArr2[500] = {};
then, for the sake of clarity, assign the lengths from your arguments to two integers, casting them since the compiler might warn you about incompatibility between size_t and int.
int lenArg1 = 0;
int lenArg2 = 0;
lenArg1 = (int)strlen ( argv[1] );
lenArg2 = (int)strlen ( argv[2] );
Then, printing the lengths len1 and len2 for debugging purposes only:
int len1 = strlen ( cArr1 );
int len2 = strlen ( cArr2 );
cout << "len1 >> " + to_string(len1) <<endl;
cout << "len2 >> " + to_string(len2) <<endl;
In fact, as #Kevin SUN mentioned, it was possible that your argument reading steps were missing the null characters, however, after running some tests it seems to work fine just by initializing the char arrays.
Also, as mentioned in the comments you need to increase the size reserved for res array, I did it to 500
Compiled with g++ -Wall main.cpp -o calc.exe and running: calc 10 100
Without initialization you get problems like:
after initializing, the output works just fine:

all possible combinations to divide pack of candies

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;
}

Print combinations of a string from left to right (not permutation) c++

Given a string, I want to print all the combinations, picking letters from left to right: Ex. Input: abcd
Output:
abc
acd
abd
bcd
ac
ad
bc
bd
cd
I can do it, but i cannot generalize it, for ex. in the string abcd, i can get all the mentioned combinations by deleting only one letter. Then I can do it also by deleting two letters and so on.
code:
name = "abcdefghi";
//Deleting 2 letters
for(int i = 1; i < name.size(); i++){
for(int k = 2; k < name.size(); k++){
for(int j = 0; j < name.size(); j++){ // PRINT ARRAY
if(j != i && j != k) cout << name[j];
}
cout << endl;
}
}
// Deleting 1 letter:
for(int i = 1; i < name.size(); i++){
for(int j = 0; j < name.size(); j++){ // PRINT ARRAY
if(j != i) cout << name[j];
}
cout << endl;
}
How can I generalize it so that I can first print the combination with 1 letter missing, then 2 letters missing, then 3, and so on...
Because if I keep going like this, to get all the combinations with the number of letters missing from 1 to n, I will need n number of for loops...
You can do it like this for example:
print_combinations(const string& name) {
if(name.size() > 1) {
for(int i = 0; i < name.size(); ++i) {
string name2 = name;
name2.erase(i, 1);
cout << name2;
}
for(int i = 0; i < name.size(); ++i) {
string name2 = name;
name2.erase(i, 1);
print_combinations(name2);
}
}
}
Currently, you can use a counter and use it as flag, something like:
void print_combinations(const std::string& s)
{
if (s.size() >= 32) {
return; // String too long
}
std::uint32_t end = 1u << s.size();
for (std::uint32_t i = 0; i != end; ++i)
{
auto j = i;
for (const auto c : s)
{
if ((j & 1) != 0) {
std::cout << c;
}
j >>= 1;
}
std::cout << std::endl;
}
}
Demo

Recursion of for's

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.