【问题标题】:Generate string lexicographically larger than input按字典顺序生成大于输入的字符串
【发布时间】:2021-12-05 00:02:56
【问题描述】:

给定一个输入字符串A,是否有一种简洁的方法可以生成一个在字典上大于A 的字符串B,即A < B == true

我的原始解决方案是:

B = A;
++B.back();

但通常这不起作用,因为:

  1. A 可能为空
  2. A 的最后一个字符可能接近环绕,在这种情况下,生成的字符将具有较小的值,即 B < A
  3. 每次都添加一个额外的字符是一种浪费,而且会很快出现在不合理的大字符串中。

所以我想知道是否有一个标准库函数可以帮助我,或者当我想从任意字符串开始时是否有一个可以很好地扩展的策略。

【问题讨论】:

  • A 实际上是空的,你想要的答案是什么?
  • @cigien 任何产生A < B 的答案都是可以接受的。一个好的答案将避免以需要后续调用向输入字符串添加字符的方式“花费”可用范围。我已将我当前的解决方案发布为对常见案例的虚拟处理(我对此还不满意)

标签: c++ string c++-standard-library


【解决方案1】:

这是我的虚拟解决方案:

std::string make_greater_string(std::string const &input)
{
    std::string ret{std::numeric_limits<
                    std::string::value_type>::min()};
 
    if (!input.empty())
    {
        if (std::numeric_limits<std::string::value_type>::max() 
            == input.back())
        {
            ret = input + ret;
        }   
        else
        {   
            ret = input;
            ++ret.back();
        }   
    }
   
    return ret;
}

理想情况下,我希望避免对所有特殊情况进行显式处理,并使用一些可以更自然地处理它们的工具。已经在查看@JosephLarson 的答案,我发现我可以比最后一个字符增加更多,这样可以在不添加更多字符的情况下改善可实现的范围。

以下是本文建议后的改进:

std::string make_greater_string(std::string const &input)
{
    constexpr char minC = ' ', maxC = '~';
    // Working with limits was a pain, 
    // using ASCII typical limit values instead.
    
    std::string ret{minC};
 
    auto rit = input.rbegin(); 
    while (rit != input.rend())
    {
        if (maxC == *rit)
        {
            ++rit;
            if (rit == input.rend())
            {
                ret = input + ret;
                break;
            }
        }
        else
        {
            ret = input;
            ++(*(ret.rbegin() + std::distance(input.rbegin(), rit)));
            break;
        }
    }
   
    return ret;
}

Demo

【讨论】:

    【解决方案2】:

    您可以复制字符串并附加一些字母 - 这将产生更大的字典结果。

        B = A + "a"
    

    【讨论】:

    • 在问题中,我在(3)中提到:Adding an extra character every time is wasteful and will quickly in unreasonably large strings
    【解决方案3】:

    您可以将 A 复制到 B 中,然后查看最后一个字符。如果最后一个字符不是您范围内的最后一个字符,那么您只需将其加一即可。

    否则,您可以查看 last-1、last-2、last-3。如果您到达字符列表的前面,则追加到长度。

    【讨论】:

    • 啊哈,所以在我的实现中,我忘记使用最后一个字符作为“增加”字符串值的手段。
    猜你喜欢
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-29
    • 2020-12-17
    • 1970-01-01
    相关资源
    最近更新 更多