通过分而治之找到子字符串

时间:2019-04-03 03:01:01

标签: c++

我正在尝试编写分而治之的实现方案来解决以下问题:

给出一个字符串“ S”,找到“ S”中所有包含给定集合中所有元素且无重复的子字符串。

例如:

S =“ abcdeabcdeeabcd”; set = {a,b,c,d,e};应该返回子字符串 'abcde','abcde'和'eabcd'

在'x'上,我在字符串的前半部分找到了很多子字符串,在'y'上,我在字符串的后半部分找到了很多子字符串。

问题来自于'combine'方法,如何获取位于“ abcdeabcdeeabcd”中间的子字符串?

我的算法执行以下操作:

//在这4个部分中找不到任何子字符串。

"abc" "deab  "cdee" "abcd"

//合并前2个和后2个

//在第一部分找到一个子字符串,在第二部分找到另一个

abcde ab”“ cde eabcd

//现在,合并两个部分之后,如何还可以找到之前找到的两个子字符串中间的子字符串?

"abcdeabcdeeabcd"

2 个答案:

答案 0 :(得分:0)

似乎最好以第一个字母开头并构造以该字母开头的所有可能的子字符串(a,ab,abc,abcd,abcde)。首个字母就是这样。现在,执行第二个字母,依此类推。 –在进入input_str的末尾时,请务必小心,不要超过字符串的末尾。

不确定如何处理重复项或应如何提供输出。如果您有任何问题,请告诉我。

#include <iostream>
#include <string>
#include <set>

using namespace std;

/// For each letter in the string, determine if that letter exists in the letter_set.
bool is_string_contained_by_set(const std::string &str,
                                const std::set<char> &letter_set)
{
  for (const auto &letter: str) {
    // if any letter is not in the letter_set, then return false
    if (letter_set.find(letter) == letter_set.end())
      return false;
  }
  // all letters were in teh letter_set, so return true.
  return true;
}

// find all the substrings starting with a given letter up to the length of
// the number of letters in the letter_set.
void find_strings(const std::string &str, const std::set<char> &letter_set)
{
  // create substrings, by starting with the first letter and adding
  // successive letters in sequence up to the number of letters in letter_set
  for (int i = 0; i < letter_set.size(); i++) { // generate all substrings
    std::string substring{str.begin(), str.begin() + i + 1};
    // Check to see if the substring's letters are found in the letter_set
    if (is_string_contained_by_set(substring, letter_set)) {
      std::cout << substring << " \n";
    }
  }
}

int main()
{
  const std::string input_str{"abcdeabcdeeabcd"};
  const std::set<char> letter_set{'a','b', 'c', 'd', 'e'};

  auto start = input_str.begin();
  auto end = input_str.end();

  // loop through each string from the beginning of the input_str
  // find_strings() will only use a substring up to the size of letter_set,
  // so there is no need to check that here.
  // Here, we are just making sure that as we get to the end of str, we don't
  // pass anything beyond the end of the input_str.
  while ( start != input_str.end()) {
    find_strings(std::string{start, end}, letter_set);
    start++;
  }
}

答案 1 :(得分:0)

无需使用分而治之的技术来解决此问题。可以使用“滑动窗口”技术轻松解决。如果您坚持使用分而治之来解决问题,那么您可以尝试以下方法:在递归函数startPos中添加一个参数。检查从此位置开始且长度等于集合长度的子字符串,并使用startPos调用递归。基本为:startPos == len(str)-len(set)+1