当前位置: 首页 > 知识库问答 >
问题:

算法:将字符串最优分割为3个子字符串

秦建元
2023-03-14

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

例如,以字符串 k = “阿纳孔达”为例。拆分它的最佳方法是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 ",该算法将不起作用。我不知道如何正确解决这个问题。所以,我要求一个理论上的解决方案,这样我就可以试着自己实现它。

共有1个答案

冯枫
2023-03-14

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

#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++)
std::string ss[3] = {s.substr(0, j+1), s.substr(j+1, i-j), s.substr(i+1)};
if (r < res || res == "") res = r;
 类似资料:
  • 当我尝试用分隔符“|”拆分字符串时,它似乎拆分了每个字符。 这是我的线,导致了问题:

  • 问题内容: 是否可以每个字符分割一个字符串? 例如,假设我有一个包含以下内容的字符串: 我怎样才能使它看起来像这样: 问题答案: 192 为了完整起见,你可以使用正则表达式执行此操作: 对于字符的奇数,你可以执行以下操作: 你还可以执行以下操作,以简化较长块的正则表达式: re.finditer如果字符串很长,则可以使用它逐块生成。

  • 问题内容: 每当出现“”时,我都尝试拆分字符串,例如语句test abc。然后,将每个单词中的第一个字母从头到尾移动。我将字母移动到使用原始字符串 所以我的问题是,我将如何分割字符串,然后开始在分割字符串的每个部分中移动字母? 问题答案: 您不必为此进行-transform-join;一步就能做到。 正则表达式基本上分为3组: 那么,作为替换字符串使它明显和清晰,切换和周围。 因此,应该清楚的是,

  • String 类的 split() 方法可以按指定的分割符对目标字符串进行分割,分割后的内容存放在字符串数组中。该方法主要有如下两种重载形式: 其中它们的含义如下: str 为需要分割的目标字符串。 sign 为指定的分割符,可以是任意字符串。 limit 表示分割后生成的字符串的限制个数,如果不指定,则表示不限制,直到将整个目标字符串完全分割为止。 使用分隔符注意如下: 1)“.”和“|”都是转

  • 本文向大家介绍Java分割字符串,包括了Java分割字符串的使用技巧和注意事项,需要的朋友参考一下 示例 您可以分割String特定的分隔字符或正则表达式,可以使用具有以下签名的方法:String.split() 请注意,定界字符或正则表达式将从结果字符串数组中删除。 使用分隔字符的示例: 使用正则表达式的示例: 您甚至可以直接拆分String文字: 警告:不要忘记该参数始终被视为正则表达式。 在

  • 在字符串中分隔符的最后一次出现时拆分字符串的推荐Python习惯用法是什么?例如: 接受第二个参数,该参数是要拆分的分隔符的引用。与常规列表索引一样,表示从末尾开始的最后一个。如何做到这一点?