Recombine strings based on occurrences of a pattern

Viewed 90

I'm trying to create a method called recombine which takes as input 3 strings s1,s2, and s3. This method will recombine strings s1 and s2 using s3 using the following format:

string s1Prime = s1_Left + s3 + s2_Right; //s1Prime is s1 after recombination

string s2Prime = s2_Left + s3 + s1_Right;//s2Prime is s2 after recombination

Recombine method code

void recombine(string s1, string s2, string s3)
{
  int s1PatternIndex = s1.find(s3);
  int s2PatternIndex = s2.find(s3);

  string s1_Left = s1.substr(0,s1PatternIndex); //stores all of ```s1``` characters that are to the left of ```s3```
  string s1_Right = s1.substr(s1PatternIndex + s3.length(), s1.length()); //stores all of ```s1``` characters that are to the right of ```s3```
  
  string s2_Left = s2.substr(0,s2PatternIndex); //stores all of ```s2``` characters that are to the left of ```s3```
  string s2_Right = s2.substr(s2PatternIndex + s3.length(), s2.length()); //stores all of ```s2``` characters that are to the right of ```s3```

  string s1Prime = s1_Left + s3 + s2_Right; //```s1``` after recombination
  string s2Prime = s2_Left + s3 + s1_Right; //```s2``` after recombination

  cout << s1Prime << endl;
  cout << s2Prime << endl;
}

Testing recombine method

string s1 = "AGCGADA";
string s2 = "ATTGCG";
string s3 = "GC";

recombine(s1,s2,s3);

//Console output:
// s1Prime: AGCG
// s2Prime: ATTGCGADA

My current method only works if s3 occurs only ONCE in s1 and s2, but I'm trying to make it do the recombination for more than 1 occurrence.

For example:

If s1 = "AGCGAGCA" and s2 = "TAGCTTGCGAT" and s3 = "GC"

In this example s3 exists twice in s1 and twice in s2, so there would be 4 different possibilities and eight different recombinations ( 4 for s1 and 4 for s2)

The 4 different possibilities are:

  1. Taking the 1st occurrence of s3 in s1 and 1st occurrence of s3 in s2

  2. Taking the 1st of occurrence of s3 in s1 and 2nd occurrence of s3 in s2

  3. Taking the 2nd occurrence of s3 in s1 and 1st occurrence of s3 in s2

  4. Taking the 2nd occurrence of s3 in s1 and 2nd occurrence of s3 in s2

Please suggest how to implement this in my code.

1 Answers

Given a string like AGCGAGCA, what you can do is write a function that returns pairs of strings. Each pair is the left side, and right side of a particular occurrence of the pattern being matched, e.g.

  AGCGAGCA  with pattern GC
gives
 {AG, AGCA}
 {AGCGA, A}

Here's the function:

auto lefts_and_rights(std::string_view input, std::string_view pattern)
{
    std::vector<std::pair<std::string_view, std::string_view>> res;

    auto pos = std::string::npos;
    while((pos = input.find(pattern, pos + 1)) != std::string::npos)
        res.push_back(std::make_pair(input.substr(0, pos), 
                                     input.substr(pos + pattern.length())));
    
    return res;
}

Now you can write recombine conveniently like this:

void recombine(std::string_view s1, std::string_view s2, std::string_view s3)
{
    for (auto [left_s1, right_s1] : lefts_and_rights(s1, s3))
        for (auto [left_s2, right_s2] : lefts_and_rights(s2, s3))
        {
            std::cout << left_s1 << s3 << right_s1 << "\n";
            std::cout << left_s2 << s3 << right_s2 << "\n";
        }
}

Here's a demo.

Related