将相邻的子串组合在一起并查找计数

时间:2016-11-22 07:12:22

标签: c++ c

嗨,这是我在面试中被要求用C / C ++编写代码的问题。

给定一个字符串,您将获得可能的操作。 我们可以对相邻的子串进行分组,例如ABCABCBC可以压缩为 2ABC1BC或1ABCA2BC

在所有可能的选项中,任务是找到具有最小长度的结果字符串。

如果有多个解决方案,则返回按字典顺序排列的最小字符串。 因此对于上面的例子,解决方案是2ABC1BC

另一个例子是 FLFLAFLAFLAF 解决方案:1FLF3LAF

我知道可以使用后缀树或置换/递归方法来完成,但无法获得如何使用的逻辑。请帮帮忙?

1 个答案:

答案 0 :(得分:0)

压缩输入前缀并在输入的其余部分递归调用自身的算法可以做到(live demo):

#include <iostream>
#include <string>
#include <limits>
#include <cstring>
using namespace std;

// determine how many times the prefix of specific length is repeated in the input
int repetitions(string const & input, int prefix_length)
{
    int i = 1;
    while (
        (i + 1) * prefix_length <= input.size() && 
        memcmp(input.data(), input.data() + i * prefix_length, prefix_length) == 0
        )
    {
        ++i;
    }

    return i;
}

// recursively compress input and return compressed string
string compress(string const & input)
{
    // recursion termination
    if (input.empty())
        return string();

    string best;
    int best_length = numeric_limits<int>::max();

    // try various prefix lengths
    for (int prefix_length = 1; prefix_length <= input.length(); ++prefix_length)
    {
        const auto max_count = repetitions(input, prefix_length);

        // try various number of repetitions up to the maximum possible
        for (int count = 1; count <= max_count; ++count)
        {
            // the candidate is compressed prefix and the rest of input compressed recursively
            const auto current = 
                to_string(count) + input.substr(0, prefix_length) + // compressed prefix
                compress(input.substr(prefix_length * count)); // the rest of input compressed recursively

            // store candidate if it is better than the currently best
            if (current.length() < best_length)
            {
                best = current;
                best_length = current.length();
            }
        }
    }

    return best;
}

int main() 
{
    string input;
    cin >> input;
    cout << compress(input);
    return 0;
}

请注意,这只是一个简单易用的解决方案。它效率不高,并且在长输入时会出现堆栈溢出。