bool compareNat(const std::string& a, const std::string& b){
if (a.empty())
return true;
if (b.empty())
return false;
if (std::isdigit(a[0]) && !std::isdigit(b[0]))
return true;
if (!std::isdigit(a[0]) && std::isdigit(b[0]))
return false;
if (!std::isdigit(a[0]) && !std::isdigit(b[0]))
{
if (a[0] == b[0])
return compareNat(a.substr(1), b.substr(1));
return (toUpper(a) < toUpper(b));
//toUpper() is a function to convert a std::string to uppercase.
}
// Both strings begin with digit --> parse both numbers
std::istringstream issa(a);
std::istringstream issb(b);
int ia, ib;
issa >> ia;
issb >> ib;
if (ia != ib)
return ia < ib;
// Numbers are the same --> remove numbers and recurse
std::string anew, bnew;
std::getline(issa, anew);
std::getline(issb, bnew);
return (compareNat(anew, bnew));
}
为了解决本质上的解析问题,状态机(aka finite state automaton)是一种可行的方法。对上述解决方案不满意,我编写了一个简单的一次性早期纾困算法,该算法在性能方面优于上面建议的C/C++变体,不会遭受数字数据类型溢出错误,并且如果需要,很容易修改以添加大小写不敏感性。 源可以在here中找到
9条答案
按热度按时间bzzcjhmw1#
我问了this exact question (although in Java),被指向http://www.davekoelle.com/alphanum.html,那里有一个算法和它在许多语言中的实现。
14年后更新:DaveKoelle的博客已经下线,我找不到他的实际算法,但这里有一个实现。
8wigbo562#
C++有几种自然排序实现。简要回顾:
natural_sort<>
-基于Boost. Regex。alnum.hpp
,基于Dave Koelle的alphanum algorithmnatsort
-用C编写,但在C++中很容易使用。mftmpeh83#
这就是所谓的自然排序,有一个算法here看起来很有前途。
注意非ASCII字符的问题(请参见Jeff's blog entry)。
q35jwt9p4#
部分重新发布my another answer:
toUpper()
函数:用法:
gojuced75#
为了解决本质上的解析问题,状态机(aka finite state automaton)是一种可行的方法。对上述解决方案不满意,我编写了一个简单的一次性早期纾困算法,该算法在性能方面优于上面建议的C/C++变体,不会遭受数字数据类型溢出错误,并且如果需要,很容易修改以添加大小写不敏感性。
源可以在here中找到
dwthyt8l6#
对于那些已经在项目中使用Qt的用户,可以使用
QCollator
类,详细信息请参见this question。voj3qocg7#
Avalanchesort是naturall sort的一个递归变体,它在搜索排序数据堆时运行merge。当算法运行/sorting时,即使你向排序堆添加数据,算法也是稳定的。
搜索原则很简单。只有合并才能以相同的秩运行。
找到前两个naturell运行(等级0)后,avalanchesort将其合并为等级1的运行。然后调用avalanchesort生成等级1的第二个运行,并将这两个运行合并为等级2的运行。然后调用avalancheSort在未排序数据上生成等级2的运行......
我的实现porthd/avalanchesort使用接口注入将排序从数据处理中分离出来。你可以将该算法用于数组、关联数组或列表等数据结构。
}
b4lqfgs48#
我的算法与测试代码的java版本。如果你想使用它在您的项目中,你可以定义一个比较器自己。
输出为,
0vvn1miw9#
不是很确定是不是你想要的,反正你可以试一试:-)