【问题标题】:Algorithm: Optimally splitting a string into 3 substrings算法:最佳地将一个字符串拆分为 3 个子字符串
【发布时间】:2020-10-18 19:28:42
【问题描述】:

一段时间以来,我一直试图解决这个看似非常简单的问题。给定一个字符串 k,我们必须找到将字符串 k 拆分为恰好 3 个子字符串 k1、k2、k3 的最佳方法,例如 k1 + k2 + k3 = k。当且仅当通过反转每个子字符串并将它们重新连接在一起时,拆分是最佳的,我们可以获得字典上最小的结果。

例如取一个字符串 k = "anakonda"。拆分它的最佳方法是 k1 = "a", k2 = "na", k3 = "konda" 因为反转 (k1 = "a", k2 = "an", k3 = "adnok") 我们得到 k1 + k2 + k3 = "aanadnok",这是按字典顺序排列的最小可能结果。

我的第一个方法是总是在下一个字典顺序最小的字符处结束子字符串。

std::string str = "anakonda"

int first = find_min(str, 0, str.size() - 3); // Need to have at least 3 substrings so cannot search to the end
std::reverse(str.begin(), str.begin() + first + 1);

...

但是,这种方法存在缺陷,因为给定字符串 k = "ggggffffa",该算法将无法工作。 我对如何正确解决这个问题一无所知。所以,我要求一个理论上的解决方案,以便我可以尝试自己实现它。

【问题讨论】:

  • 如果有帮助,这只是围绕3-way partition. 描述的大量额外包袱。毕竟,字符串只是一个字符数组。
  • k1,k2k3 可以为空吗?
  • 这个问题总是保证会有一个解所以k1,k2,k3 >= 1并且不能为空。
  • @emufan4568 好的,ggggffffa 的答案是什么?
  • fffggggfa 吗?

标签: string algorithm substring


【解决方案1】:

此算法解决了问题,但可能需要优化:

#include <iostream>
#include <string>

std::string foo(std::string* ss) 
{ 
    std::string res;
    for (int i = 0; i < 3; i++)
        for (int j = ss[i].size()-1; j >= 0; j--) 
        res.push_back(ss[i][j]);
    return res;
}

int main()
{
  std::string s = "ggggffffa";
  std::string res = "";
  for (unsigned int i = 1; i < s.size() - 1; i++)
    for (unsigned int j = 0; j < i; j++)
    {
        std::string ss[3] = {s.substr(0, j+1), s.substr(j+1, i-j), s.substr(i+1)};
        std::string r = foo(ss);
        if (r < res || res == "") res = r;
    }
    std::cout << res << std::endl;  
}

说明:

  1. 我们通过两个迭代器(第一个迭代器从第一个元素到字符串的末尾,第二个迭代器从零元素到第一个迭代器)这样我们就可以确定分割字符串的所有可能索引。李>
for (unsigned int i = 1; i < s.size() - 1; i++)
    for (unsigned int j = 0; j < i; j++)
  1. 在索引ij处拆分字符串并在字符串数组中写入三个子字符串;
std::string ss[3] = {s.substr(0, j+1), s.substr(j+1, i-j), s.substr(i+1)};
  1. Сall 函数foo 反转每个子字符串,连接三个部分并返回结果字符串。
  2. 检查 foo 中的结果字符串是否按字典顺序最小,然后为结果分配一个新字符串。
if (r < res || res == "") res = r;

【讨论】:

  • @גלעד ברקן 编辑后,输出正确。对于输入:“bndakonda”,输出应为“adnbdnoka”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多