T
Mir war grad etwas langweilig da habe ich mal was zusammen gebastelt.
#include <iostream>
#include <vector>
#include <algorithm>
#include <cctype>
#include <cstdlib>
// interpret numbers in string comparison so e.g. a5 comes before a11
class natural_string_compare
{
public:
bool operator()(const std::string& s1, const std::string& s2)
{
size_t i_s1 = 0, i_s2 = 0;
int num1,num2;
char c1,c2;
while(i_s1 < s1.size() && i_s2 < s2.size()){
//skip whitespace
if(std::isspace(s1[i_s1])){
++i_s1;
continue;
}
if(std::isspace(s2[i_s2])){
++i_s2;
continue;
}
// read the next token from both strings
bool s1_isnum = read_token(s1, i_s1, num1, c1);
bool s2_isnum = read_token(s2, i_s2, num2, c2);
// if both tokens are numbers simply compare them
if(s1_isnum && s2_isnum){
if(num1 != num2) return num1 < num2;
continue;
}
// numbers go before characters
if(s1_isnum && !s2_isnum) return true;
if(!s1_isnum && s2_isnum) return false;
// if both tokens are characters simply compare them
if(c1 != c2) return c1 < c2;
}
// shorter strings go before longer strings
return s1.size() < s2.size();
}
private:
// read a token this can either be a number or a character
// returns true when the current token is a number and false when its a character
bool read_token(const std::string& s, size_t& pos, int& num, char& c)
{
if(!std::isdigit(s[pos])){
c = s[pos++];
return false;
}
num = 0;
while(std::isdigit(s[pos])){
add_digit(num, s[pos++]);
}
return true;
}
// build number out of chars
void add_digit(int& num, char c)
{
num *= 10;
switch(c){
case '1': num += 1; break;
case '2': num += 2; break;
case '3': num += 3; break;
case '4': num += 4; break;
case '5': num += 5; break;
case '6': num += 6; break;
case '7': num += 7; break;
case '8': num += 8; break;
case '9': num += 9; break;
}
}
};
int main()
{
const int MAX_NUM = 1000;
// Generate MAX_NUM random strings
std::srand((unsigned)std::time(0));
char alphanum[] = {'a','b','c','d','e','f','g','h','i','j','k','l',
'm','n','o','p','q','r','s','t','u','v','w','x',
'y','z','0','1','2','3','4','5','6','7','8','9',' '};
std::vector<std::string> v;
for(int i=0; i<MAX_NUM; ++i){
int len =(rand()%15)+1;
std::string s;
for(int j=0; j<len; ++j){
s.push_back(alphanum[(rand()%37)]);
}
v.push_back(s);
}
// Sort the strings using the natural_string_compare predicate
std::cout <<"begin sort"<<std::endl;
std::sort(v.begin(),v.end(),natural_string_compare());
for(int i = 0; i < v.size(); ++i){
std::cout << v[i] << '\n';
}
}