String concatenation to generate complementary removals

70 views Asked by At

This question is a slight alteration of this post. Given a string, I want to generate a vector of strings with x removals. For instance:

String a = "ABCD";
int x = 2;
//vector<string> residue = generate(a, x);
//vector residue would have the following elements: 
//"AB", "BC", "CD", "AC" "AD", "BD" 

Having done this, I would like to generate a second vector of strings that contains strings with the other 2 characters removed. However, in place of the removals, I would like to insert .. For instance:

//vector<string> residue2 would have the following elements:
//"..CD", "A..D", "AB..", ".B.D", ".BC.", "A.C."

Here is my attempt at doing this for x = 1. However, I am not able to generate the 2nd string or generalize for x equals any number.

vector<int> orignal; 
for(int i = 1; i <= 5; i++) original.push_back(i);
vector<int> data2;
for(int p1 = 0; p1 < length; p1++){
    auto data1 = original
    data1.erase(data1.begin()+p1);
    for(int p2 = 0; p2 < length; p2++){
        data2 = original;
        if(p2 != p1)
            data2.erase(data2.begin()+p2);
        //do stuff
    }
}

Edit: What I want to achieve is the following: (refer to my pseudo-code for x=1) Let's say original = {1, 2, 3}. Then in the first iteration of the outer for-loop, data1 = {2,3} and data2 = {1,2,3} then data2={1,2,.}. In the 2nd iteration of the outer for-loop, data1 = {1,3} and data2 = {1,2,.} then data2={.,2,3}. And then this continues one more time for data1 = {1,2}. Now this is when I am only removing one element from original. However, I would like to generalize this so that data1 will have any x removals for x < length. And consequently, data2 will also have x removals, but it will methodically remove elements that have not already been removed in data1.

2

There are 2 answers

2
Walter On BEST ANSWER

You can use std::next_permutation() to loop over all permutations of a set of bool (representing in or out). For example

#include <string>
#include <vector>
#include <algorithm>

std::vector<std::string> generate(std::string const&str, std::size_t x)
{
  const auto size = str.size();
  std::vector<bool> perm(size);
  for(std::size_t i=0; i!=size; ++i)
    perm[i] = i>=x;
  std::vector<std::string> result;
  do {
    auto copy = str;
    for(std::size_t i=0; i!=size; ++i)
      if(!perm[i]) copy[i]='.';
    result.push_back(std::move(copy));
  } while(std::next_permutation(perm.begin(),perm.end()));
  return result;
}

For example for str="ABCDE" x=2 we get

{"..CDE",".B.DE",".BC.E",".BCD.","A..DE","A.C.E","A.CD.","AB..E","AB.D.","ABC.."}
0
user2736738 On

Suppose your string length is n. And x<=n.

So make a string with x 1's and n-x 0's.

string your_string="...";
for(int i=0;i<n;i++)
     ss+=(i<=n-x-1)?"0":"1";


do
{
   string temp="";
   for(int i=0;i<=n-1;i++)
     if(ss[i]=='1')
        temp+=".";
     else
        temp+=your_string[i];
   /*  process temp..*/
}
while(next_permutation(ss.begin(),ss.end())

Example

for n=3 x=2
"ABC"
A..  011
.B.  101
..C  110