C++ string sort like a human being?

后端 未结 4 2069
灰色年华
灰色年华 2021-02-05 23:12

I would like to sort alphanumeric strings the way a human being would sort them. I.e., \"A2\" comes before \"A10\", and \"a\" certainly comes before \"Z\"! Is there any way to d

相关标签:
4条回答
  • 2021-02-05 23:55

    It really depends what you mean by "parser." If you want to avoid writing a parser, I would think you should avail yourself of library functions.

    • Treat the string as a sequence of subsequences which are uniformly alphabetic, numeric, or "other."
    • Get the next alphanumeric sequence of each string using isalnum and backtrack-checking for + or - if it is a number. Use strtold in-place to find the end of a numeric subsequence.
    • If one is numeric and one is alphabetic, the string with the numeric subsequence comes first.
    • If one string has run out of characters, it comes first.
    • Use strcoll to compare alphabetic subsequences within the current locale.
    • Use strtold to compare numeric subsequences within the current locale.
    • Repeat until finished with one or both strings.
    • Break ties with strcmp.

    This algorithm has something of a weakness in comparing numeric strings which exceed the precision of long double.

    0 讨论(0)
  • 2021-02-05 23:55

    Is there any way to do it without writing a mini parser? I would think the answer is no. But writing a parser isn't that tough. I had to do this a while ago to sort our company's stock numbers. Basically just scan the number and turn it into an array. Check the "type" of every character: alpha, number, maybe you have others you need to deal with special. Like I had to treat hyphens special because we wanted A-B-C to sort before AB-A. Then start peeling off characters. As long as they are the same type as the first character, they go into the same bucket. Once the type changes, you start putting them in a different bucket. Then you also need a compare function that compares bucket-by-bucket. When both buckets are alpha, you just do a normal alpha compare. When both are digits, convert both to integer and do an integer compare, or pad the shorter to the length of the longer or something equivalent. When they're different types, you'll need a rule for how those compare, like does A-A come before or after A-1 ?

    It's not a trivial job and you have to come up with rules for all the odd cases that may arise, but I would think you could get it together in a few hours of work.

    0 讨论(0)
  • 2021-02-06 00:02

    Is there any way to do with without writing a mini-parser?

    Let someone else do that?

    I'm using this implementation: http://www.davekoelle.com/alphanum.html, I've modified it to support wchar_t, too.

    0 讨论(0)
  • 2021-02-06 00:17

    Without any parsing, there's no way to compare human written numbers (high values first with leading zeroes stripped) and normal characters as part of the same string.

    The parsing doesn't need to be terribly complex though. A simple hash table to deal with things like case sensitivity and stripping special characters ('A'='a'=1,'B'='b'='2,... or 'A'=1,'a'=2,'B'=3,..., '-'=0(strip)), remap your string to an array of the hashed values, then truncate number cases (if a number is encountered and the last character was a number, multiply the last number by ten and add the current value to it).

    From there, sort as normal.

    0 讨论(0)
提交回复
热议问题