Print combinations of a string from left to right (not permutation) c++ - 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

Related

I need to print this shape in c++ but I am having issue with last row

image of shape
I have no issues with first 4 rows. 5th row is the problem. I am required to use loops but dont know how i am suppose to print 6 (-.*) with 0 spaces when all rows above follow a pattern.
Something like this should work for you
for (int i = 1; i <= 6; i++) {
for (int j = 28 - i * 3; j >= 0; j--) {
std::cout << " ";
}
for (int j = 0; j < i; j++) {
std::cout << "-.*";
}
std::cout << std::endl;
if (i == 4) i++;
}
Basically check when you are on the 4th row and just have it skip a row by incrementing your row index loop.
Something like this?
std::string repeat(std::string s, int n) {
std::string repeat;
for (int i = 0; i < n; ++i)
repeat += s;
return repeat;
}
int main()
{
int PADDING = 20;
int MAX = 7;
for (int i = 1; i < MAX; ++i) {
if (i == 5) continue;
std::string padding(3*(PADDING-MAX-i), ' ');
std::cout << padding << repeat("-.*", i) << std::endl;
}
}
Output:
-.*
-.*-.*
-.*-.*-.*
-.*-.*-.*-.*
-.*-.*-.*-.*-.*-.*
Live demo:
http://cpp.sh/6mtpx
In C (not C++):
#include <stdio.h>
int main(void) {
int height = 5;
char txt[3*height+1];
char sym[]= "-.*";
for(int i=0; i<3*height; ++i) txt[i]=sym[i%3];
txt[3*height]=0;
for(int i=0; i<height; ++i)
printf("%s%*.*s\n", (i+1==height)? &txt[3*(height-1)] : "", 3*(height+(i+1<height)), (i+1)*3, txt);
return 0;
}
Output:
Success #stdin #stdout 0s 5476KB
-.*
-.*-.*
-.*-.*-.*
-.*-.*-.*-.*
-.*-.*-.*-.*-.*-.*
IDEOne Link

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

wrap three nested for loops into recursion

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

c++ read each 3 elements in array

I am working on a project and i want to print in order each 3 elements of a string array.So if the string is "cadgfacbda" i want to be printed in the console :
**"cad gfa cbd a"**
This is the code :
string str("cadgfacbda");
for(int i = 0 ; i < 3 ; i++)
{
for(int j = i ; j < str.size() ; j +=3 )
{
cout << str[j]<<" ";
}
cout<<endl;
}
But what i get is :
c g c a
a f b
d a d
Code in one loop only:
string str("cadgfacbda");
for(int i = 0 ; i < str.size() ; i++) {
if(i && i%3==0)
cout<<" ";
cout << str[i];
}
cout<<endl;
I think it should go something like this:
string str("cadgfacbda");
for(int i = 0 ; i < str.size() ; i++)
{
cout << str[j]<<" ";
if( i % 3 == 0 )
cout<<endl;
}
This ofcourse assumes you need new line after every three elements. If you just need spaces then you can try this instead:
string str("cadgfacbda");
for(int i = 0 ; i < str.size() ; i++)
{
cout << str[j];
if( i % 3 == 0 )
cout<<" ";
}
int main()
{
typedef std::string::size_type size_type;
std::string str("cadgfacbda");
const size_type STEP_SIZE = 3;
for(size_type i = 0 ; i < str.size() ; i+=STEP_SIZE)
{
std::cout << str.substr(i, STEP_SIZE) << " ";
}
std::cout << std::endl;
return 0;
}
#include<stdio.h>
#include<string.h>
#include<string>
int main()
{
string str("cadgfacbda");
char arr[]=str.to_char();
for(int i=1;i<=strlen(arr);i++)
{
printf("%c",arr[i-1]);
if(i%3==0)
{
printf(" ");
}
}
}
This should work too:
int main()
{
std::string str = "cadgfacbda";
for (int i = 0; i < str.length()-3; i++)
{
for (int j = 0; j < 3; ++j)
{
if ((3 * i + j) < str.length())
std::cout << str[3 * i + j];
}
std::cout << " ";
}
return 0;
}
This should work :
string str("cadgfacbda");
for(int i = 0 ; i < str.size() ; i++)
{
if(i % 3 == 0 && i != 0) cout << " ";
cout << str[i];
}
cout << endl;
A bit late I suppose but you could just substring.
std::string str("cadgfacbda");
for (std::size_t i = 0; i < str.size(); i += 3) {
std::cout << str.substr(i, 3) << " ";
}
This saves you a ton of code and is imo more readable.
Live example

Simplifying C++ For Loop

at the moment I have the following code:
for(int i = 0; i < 4; i++){
cout << rowNo[i] << endl;
}
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
cout << rowNo[i] << '.';
cout << rowNo[j] << endl;
}
}
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
for(int k = 0; k < 4; k++){
cout << rowNo[i] << '.';
cout << rowNo[j] << '.';
cout << rowNo[k] << endl;
}
}
}
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
for(int k = 0; k < 4; k++){
for(int l = 0; l < 4; l++){
cout << rowNo[i] << '.';
cout << rowNo[j] << '.';
cout << rowNo[k] << '.';
cout << rowNo[l] << endl;
}
}
}
}
Where rowNo[] is an array {1,2,3,4}
And I was wondering two things:
Can this be simplified, so maybe put into some sort of recursive loop?
Following that, can this then be made for an array of size N?
Your looking for Cartesian_product
With
bool increment(std::vector<std::size_t>& v, std::size_t maxSize)
{
for (auto it = v.rbegin(); it != v.rend(); ++it) {
++*it;
if (*it != maxSize) {
return true;
}
*it = 0;
}
return false;
}
then you can do:
void print_cartesian_product(const std::vector<int>&v, int n)
{
std::vector<std::size_t> indexes(n);
do {
print(v, indexes);
} while (increment(indexes, v.size()));
}
Demo
You are actually trying to print a number encoded in base4 with digit {1, 2, 3, 4}. To achieve it, You only need to define a function to increment by one. I propose a generic solution in the term of amount of number to print and base.
Like others, I use a number to mean "empty digit", and I use zero which is quite convenient.
Complete source code :
#include <iostream>
#include <vector>
bool increment_basep(std::vector<int>& number, int p)
{
int i = 0;
while(i < number.size() && number[i] == p)
{
number[i] = 1;
++i;
}
if(i >= number.size())
return false;
++number[i];
return true;
}
void print_vect(std::vector<int>& number)
{
for(int i = number.size() -1 ; i >= 0; --i)
{
if(number[i] != 0)
std::cout << number[i];
}
std::cout << std::endl;
}
int main() {
int n = 4;
int p = 4;
std::vector<int> num4(n);
std::fill(num4.begin(), num4.end(), 0);
while(increment_basep(num4, p))
{
print_vect(num4);
}
return 0;
}
The increment return whether or not the computation has overflown. When we overflow we know we need to stop.
First solution it comes my mind is that on every loop to put in a buffer and finally to print all the buffers.
I think there are some other ingenious methods
for(int i = 0; i < 4; i++){
put in buffer1 rowNo[i]
for(int j = 0; j < 4; j++){
put in buffer2 rowNo[i],rowNo[j]
for(int k = 0; k < 4; k++){
put in buffer3 rowNo[i],rowNo[j],rowNo[k]
for(int l = 0; l < 4; l++){
put in buffer4 rowNo[i],rowNo[j],rowNo[k],rowNo[l],endl.
}
}
}
}
print(buffer1);
print(buffer2);
print(buffer3);
print(buffer4);
The following is the simplest code I came up with. There has to be a more direct way of doing this though...
It basically introduces a "ghost" index -1, corresponding to an empty place in a number. The ternary operators in the loops conditions are there to avoid duplicates.
int main()
{
int N = 4;
int rowNo[4] = {1, 2, 3, 4};
for (int i = -1; i < N; i++)
for (int j = (i > -1 ? 0 : -1); j < N; j++)
for (int k = (j > -1 ? 0 : -1); k < N; k++)
for (int l = (k > -1 ? 0 : -1); l < N; l++)
{
if (i > -1) std::cout << rowNo[i] << '.';
if (j > -1) std::cout << rowNo[j] << '.';
if (k > -1) std::cout << rowNo[k] << '.';
if (l > -1) std::cout << rowNo[l];
std::cout << std::endl;
}
}
It can of course be generalized to an array of arbitraty size, possibly with some code generation script.