如何在C ++中获取下一个前缀?

时间:2010-04-23 16:52:20

标签: c++

给定一个序列(例如字符串“Xa”),我想按字典顺序(即“Xb”)获得下一个前缀。 “aZ”的下一个应该是“b”

here

描述了这个功能有用的激励用例

由于我不想重新发明轮子,我想知道C ++ STL或boost中是否有任何函数可以帮助轻松定义这个泛型函数? 如果没有,你认为这个功能有用吗?

备注

  • 即使示例是字符串,该函数也适用于任何序列。
  • 词典顺序应该是函数的模板参数。

从答案中我得出结论,C ++ / Boost上没有任何内容可以帮助您轻松地定义这个泛型函数,而且这个函数太具体了,不能免费提出。我将实现一个通用的next_prefix,之后如果你觉得它有用,我会请求。

我接受了单一答案,即使提议的实施不是通用的,也会提供一些关于如何做到这一点的提示。

5 个答案:

答案 0 :(得分:3)

我不确定我是否理解您希望字符串转换的语义,但是类似下面的内容可能是您的起点。代码将递增序列,就好像它是一个表示数字的数字序列。

template<typename Bi, typename I>
bool increment(Bi first, Bi last, I minval, I maxval)
{
    if( last == first ) return false;
    while( --last != first && *last == maxval ) *last = minval;
    if( last == first && *last == maxval ) {
        *last = minval;
        return false;
    }
    ++*last;
    return true;
}

也许您希望添加一个带有函数对象的重载,或者为基元添加重载或特化。几个例子:

string s1("aaz");
increment(s1.begin(), s1.end(), 'a', 'z');
cout << s1 << endl;     // aba

string s2("95");
do {
    cout << s2 << ' ';  // 95 96 97 98 99
} while( increment(s2.begin(), s2.end(), '0', '9') );
cout << endl;

答案 1 :(得分:2)

这看起来如此具体,以至于我看不出它会如何进入STL或提升。

答案 2 :(得分:0)

当您说订单是模板参数时,您要设想的是什么?一个比较器,它接受两个字符并返回bool?

如果是这样,那么这就是一场噩梦,因为找到“比我当前的char更大的char”的唯一方法是对所有字符进行排序,找到你当前的char结果,然后前进一步(或者实际上,如果某些字符可能比较相等,请使用upper_bound和当前字符来查找第一个更大的字符。)

在实践中,对于任何理智的字符串排序规则,您可以更有效地定义“获取下一个字符,或警告我,如果我给你最后一个字符”功能,并在此基础上构建“获取下一个前缀”功能。希望允许任意顺序比你需要的更灵活。

答案 3 :(得分:0)

通常将订单指定为比较器,而不是序列生成器。

词典排序特别倾向于仅部分,例如,在情况或变音不敏感的情况下。因此,您的最终产品将是不确定的,或者至多是任意的。 (“总是选择最低数字编码”?)

在任何情况下,如果您接受比较器作为输入,则将其转换为增量操作的唯一方法是将当前值与字符空间中的每个其他值进行比较。哪个可以工作,127个值太少(比较器排序表会使问题缩短),或者如果你使用任何其他类型的字符,可能会非常慢。

答案 4 :(得分:0)

最好的方法是以某种方式定义字符排序,然后定义从一个字符到两个字符到三个字符的规则。

使用您希望在要包含的完整字符列表中使用的任何排序函数,然后将其用作排序。找到当前字符的索引,您可以轻松找到上一个和下一个字符。只推进最右边的角色,除非它会翻身,然后将下一个角色推进到左边。

换句话说,重新发明轮子就像是10行Python。可能少于500行C ++。 :)