рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде Go рдореЗрдВ рдХреЛрдб рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛

рдЫрд╡рд┐ "рдореИрдВ Google рдкрд░ рдПрдХ рдЯрд░реНрдирдХреА рд╕рдорд╛рдзрд╛рди рдХреЗ рд▓рд┐рдП рдЬрд╛рдКрдВрдЧрд╛"

рдХрд┐рд╕реА рднреА рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдЙрддреНрдкрд╛рдж рдкрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рдбреЗрд╡рд▓рдкрд░ рдХреЛ рдХрд┐рд╕реА рдФрд░ рдХреЗ рдХреЛрдб рдХреЛ рдЙрдзрд╛рд░ рд▓реЗрдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рд╣рд░ рд╕рдордп рд╣реЛрддрд╛ рд╣реИред рд╣рд░ рд╕рд╛рд▓, рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдЬрд┐рдХ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд╕рд╛рде, рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рдкреНрд░рд╛рдХреГрддрд┐рдХ рдФрд░ рдЪрд┐рдХрдиреА рд╣реЛ рдЬрд╛рддреА рд╣реИред рднреВрд▓ рдЧрдП рдХрд┐ рдПрдХ рдлрд╛рдЗрд▓ рд╕реЗ рд╕рднреА рд╢рдмреНрдж рдХреИрд╕реЗ рдирд┐рдХрд╛рд▓реЗ? рдХреЛрдИ рдмрд╛рдд рдирд╣реАрдВ, рд╕реНрдЯреИрдХ рдУрд╡рд░рдлреНрд▓реЛ рдкрд░ рдЬрд╛рдПрдВ рдФрд░ рдПрдХ рддреИрдпрд╛рд░ рд╕реНрдирд┐рдкреЗрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЙрдиреНрдирдд рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЙрджрд╛рддреНрдд рдкрд╛рда рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд▓рдЧрдЗрди рднреА рд╣реИ, рдЬреЛ рд╣реЙрдЯрдХреА рджреНрд╡рд╛рд░рд╛, SO рдкрд░ рдЪрдпрдирд┐рдд рдкрд╛рда рдХреА рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкреНрд░рд╛рдкреНрдд рдЙрддреНрддрд░ рд╕реЗ рдХреЛрдб рдХрд╛ рдПрдХ рдЯреБрдХрдбрд╝рд╛ рд╕реАрдзреЗ рд╕рдВрдкрд╛рджрдХ рдореЗрдВ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрдИ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИ ...

рдпрджреНрдпрдкрд┐ рдКрдкрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдЙрджрд╛рд╣рд░рдг рдЪрд░рдо рд╣реИ рдФрд░ рдПрдХ рдЕрдЪреНрдЫреЗ рдордЬрд╛рдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд╡рд╕рд░ рднреА рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИред рдЪрд┐рддреНрд░ рдзреНрдпрд╛рди рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдлреНрд▓реЛрдЯ64 рд╕рд░рдгреА рдХреЛ рдЫрд╛рдБрдЯрдиреЗ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рджрд┐рдЦрд╛рддрд╛ рд╣реИред рдореИрдВ рдпрд╣ рдирд╣реАрдВ рд╕реЛрдЪрдирд╛ рдЪрд╛рд╣рддрд╛ рдХрд┐ рдЗрд╕реЗ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЗ рдПрдХ рд╕рд░рдгреА рдХреЗ рд░реВрдк рдореЗрдВ рдХреНрдпреЛрдВ рдХреНрд░рдордмрджреНрдз рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ; рд╣рдо рдЗрд╕ рд╕рд╡рд╛рд▓ рдХреЛ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкреНрд░реЗрдорд┐рдпреЛрдВ рдкрд░ рдЫреЛрдбрд╝ рджреЗрдВрдЧреЗред рдореБрдЭреЗ рдЧреЛ рдкрд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдорд╛рдирд╡ рдЫрдВрдЯрд╛рдИ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА, рдЗрд╕рд▓рд┐рдП рдКрдкрд░ рдХреЗ рдирд╛рдпрдХ рдХреА рддрд░рд╣, рдореЗрд░рд╛ рд░рд╛рд╕реНрддрд╛ Google рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рд╛ рдЧрдпрд╛ред

рдбрд┐рд╕реНрдХреНрд▓реЗрдорд░: рдпрд╣ рдкреЛрд╕реНрдЯ рд╡рд┐рдХрд╛рд╕ рд╕рдВрд╕реНрдХреГрддрд┐ рдХреЛ рд╕рдорд░реНрдкрд┐рдд рд╣реИ рдФрд░ рдЧреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдХреБрдЫ рд▓рд╛рднреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдкрдХреНрд╖рдкрд╛рддреА рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирдХрд╛рд░рд╛рддреНрдордХ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдЖрдЧреЗ рдирд╣реАрдВ рдкрдврд╝рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рдпрд╛рддреНрд░рд╛


"рдорд╛рдирд╡ рд╕реЙрд░реНрдЯ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕" рдХреНрд╡реЗрд░реА рдХрд╛ рдкрд╣рд▓рд╛ рд▓рд┐рдВрдХ 2007 рдХреЗ рд▓реЗрдЦ @CodingHorror (рдЬреЗрдл рдПрдЯрд╡реБрдб) рд╕реЗ рдЖрдпрд╛ рдерд╛ред рдПрдХ рд╕рдореНрдорд╛рдирд┐рдд рд╡реНрдпрдХреНрддрд┐, рд╡рд╣ рдмреБрд░реЗ рдХреА рд╕рд▓рд╛рд╣ рдирд╣реАрдВ рджреЗрдЧрд╛ред рджрд┐рдП рдЧрдП рд▓рд┐рдВрдХ рдЕрднреА рднреА рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рднреА рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдПрдХ рдкреВрд░рд╛ рдЧреБрдЪреНрдЫрд╛ рд╣реИред

рдкрд╛рдпрдерди рдХреЗ рддрд╣рдд рдЬреЗрдл рдХреА рдкрд╕рдВрдж рдЗрд╕ рддрд░рд╣ рд╣реИ:
import re def sort_nicely( l ): """ Sort the given list in the way that humans expect. """ convert = lambda text: int(text) if text.isdigit() else text alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ] l.sort( key=alphanum_key ) 


рдареАрдХ рд╣реИ рдЗрд╕рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ? рд▓реЛрдЧ рдЖрдорддреМрд░ рдкрд░ рдХреНрдпрд╛ рдХрд░рддреЗ рд╣реИрдВ? рдмрд╕ рдХреЛрдИ рд╡рд┐рдХрд▓реНрдк рдирд╣реАрдВ рд╣реИ - рдЖрдк рдХреЛрдб рдХреЗ рдЗрд╕ рдЯреБрдХрдбрд╝реЗ рдХреЛ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рд▓реЗ рдЬрд╛рдПрдВ, рдФрд░ рд╕рд╣реА рдЬрдЧрд╣ рдкрд░ рдХреЙрдкреА рдХрд░реЗрдВред 10 рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ - 10 рд╕реНрдерд╛рдиред рдереЛрдбрд╝рд╛ рдФрд░ рдЕрдзрд┐рдХ рддрд░реНрдХрд╕рдВрдЧрдд рд▓реЛрдЧреЛрдВ рдиреЗ рдлрд╝рд╛рдЗрд▓ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЙрдкрдпреЛрдЧреА рдЪреАрдЬреЗрдВ рд░рдЦреАрдВ, рдкреНрд░рддреНрдпреЗрдХ рдХреА рдЕрдкрдиреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИред
рдЖрдкрдХрд╛ рдЕрдЧрд▓рд╛ рдбреЗрд╡рд▓рдкрд░ рдЖрдкрдХреЗ рдХреЛрдб рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рд╕рд╛рдЗрдЯ рдкрд░ рдареЛрдХрд░ рдЦрд╛рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐:

  1. "рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рдордиреБрд╖реНрдп рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВ" , рдФрд░ рд╡реЗ рдХреИрд╕реЗ рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВ?
  2. alphanum_key рджреНрд╡рд╛рд░рд╛ рдЫрдБрдЯрд╛рдИ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИ? рдЖрдкрдХреЛ рд╕реЛрдЪрдирд╛ рд╣реЛрдЧрд╛ ...
  3. (рдкреНрд░рд▓реЗрдЦрди рдХреЗ 2 рдШрдВрдЯреЗ рдкреНрд░рдпреЛрдЧ рдХрд░рдиреЗ рдФрд░ рдкрдврд╝рдиреЗ рдХреЗ рдмрд╛рдж ) рд▓рд╛рдирдд рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдЦрд┐рд░рдХрд╛рд░ ['01', '001', '01', '001'] nifiga рдкрд░ рдХрд╛рдо рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡рд┐рдирд┐рд░реНрджреЗрд╢рди рдХреЗ рдЕрдиреБрд╕рд╛рд░ sort рд╕реНрдерд┐рд░ рд╣реИ рдФрд░ рдЗрди рдЯреБрдХрдбрд╝реЛрдВ рдХреА key рд╕рдорд╛рди рд╣реИ;
  4. рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреИрд╕реЗ? рдФрд░ рдЕрдЧрд░ 10,000 рддрддреНрд╡ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ re.split ; рдЫрд╡рд┐
  5. рдмрдВрдж рдХрд░реЛ, рд▓реЗрдХрд┐рди рдореИрдВ рдЖрдо рддреМрд░ рдкрд░ рдЧреЛ рдкрд░ рд▓рд┐рдЦрддрд╛ рд╣реВрдВ, рдореБрдЭреЗ рдЖрдкрдХреЗ рд╡рди-рд▓рд╛рдЗрдирд░реНрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд╡реИрд╕реЗ рднреА рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИред

C # рдХреЛрдб рднреА RegExp рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, C ++ рдХреЛрдб рдореЗрдВ рдЖрдорддреМрд░ рдкрд░ рдпреВрд░реЗрдирд┐рдпрдо рднрд╛рд▓реВ рдФрд░ MFC рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдЕрдиреНрдп рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рд╕рдВрд╢реЛрдзрд┐рдд MFC рд╕рдВрд╕реНрдХрд░рдг рд╣реИ рдЬрд┐рд╕реЗ рдкрд░реНрд▓ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реЗ C ++ рдореЗрдВ рдкреЛрд░реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛)ред рдореБрдЭреЗ рдпрдХреАрди рд╣реИ рдХрд┐ рдХрдИ рдкрд╛рдардХреЛрдВ рдХреЛ рдПрдХ рд╣реА рдХрд╣рд╛рдиреА рдорд┐рд▓реЗрдЧреА рдХрд┐ рд╡реЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ рдХреЗ рд╕рд╛рде рдХрдЪрд░рд╛ рдбрдВрдк рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреИрд╕реЗ рдЕрдлрд╡рд╛рд╣ рдХрд░рддреЗ рд╣реИрдВ, рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреА рдирдХрд▓ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдЦрдХреЛрдВ рдХреА рдХрд▓реНрдкрдирд╛ рдХреЛ рд╕реБрд▓рдЭрд╛рддреЗ рд╣реИрдВ, рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝рддреЗ рд╣реИрдВ ...

тАЬрдирд┐рдХрдЯрддрдо рдЕрд╕реНрдкрддрд╛рд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдпрд╛рддреНрд░рд╛ рд▓реЗ рд▓реЛред рдЖрдорддреМрд░ рдкрд░ рдЙрдирдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рдХреЗ рдЖрд╕рдкрд╛рд╕ рдореЗрдВ рдПрдХ рдЕрд╡рд┐рд╕реНрдорд░рдгреАрдп рдбрдВрдк рд╣реИ рдЬрд╣рд╛рдВ рдЖрдк рдХреБрдЫ рднреА рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдкрдХреЗ рдкреНрд░рд╛рдЗрдорд░реА рдЬрд╛рд░ - рд╕реАрд░рд┐рдВрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬрд▓реНрджреА рд╕реЗ рдЕрдкрдиреЗ рд╕рднреА рд╕рд╛рдордЧреНрд░рд┐рдпреЛрдВ рдХреЛ рдЕрдкрдиреЗ рд╢рд░реАрд░ рдореЗрдВ рдбрд╛рд▓реЗрдВ рдФрд░ рдкреНрд░рднрд╛рд╡ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВред тАЭ - рд╡рд┐рдзрд┐ рдирдВрдмрд░ 2, рджрдирд┐рдпрд╛ рд╢реЗрдкреЛрд╡рд╛рд▓реЛрд╡ред

рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЬрд╛рдУ


рдХреБрдЫ рдШрдВрдЯреЛрдВ рдореЗрдВ, рдЧреЛ рдкрд░ рд╕рдорд╛рд░реЛрд╣ рдХреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ред рдлрд┐рд░ рдореИрдВрдиреЗ рдкрд░реАрдХреНрд╖рдг, рдмреЗрдВрдЪрдорд╛рд░реНрдХ, рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ред
рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг
 // StringLess compares two alphanumeric strings correctly. func StringLess(s1, s2 string) (less bool) { // uint64 = max 19 digits n1, n2 := make([]rune, 0, 18), make([]rune, 0, 18) for i, j := 0, 0; i < len(s1) || j < len(s2); { var r1, r2 rune var w1, w2 int var d1, d2 bool // read rune from former string available if i < len(s1) { r1, w1 = utf8.DecodeRuneInString(s1[i:]) i += w1 // if digit, accumulate if d1 = ('0' <= r1 && r1 <= '9'); d1 { n1 = append(n1, r1) } } // read rune from latter string if available if j < len(s2) { r2, w2 = utf8.DecodeRuneInString(s2[j:]) j += w2 // if digit, accumulate if d2 = ('0' <= r2 && r2 <= '9'); d2 { n2 = append(n2, r2) } } // if have rune and other non-digit rune if (!d1 || !d2) && r1 > 0 && r2 > 0 { // and accumulators have digits if len(n1) > 0 && len(n2) > 0 { // make numbers from digit group in1 := digitsToNum(n1) in2 := digitsToNum(n2) // and compare if in1 != in2 { return in1 < in2 } // if equal, empty accumulators and continue n1, n2 = n1[0:0], n2[0:0] } // detect if non-digit rune from former or latter if r1 != r2 { return r1 < r2 } } } // if reached end of both strings and accumulators // have some digits if len(n1) > 0 || len(n2) > 0 { in1 := digitsToNum(n1) in2 := digitsToNum(n2) if in1 != in2 { return in1 < in2 } } // last hope return len(s1) < len(s2) } // Convert a set of runes (digits 0-9) to uint64 number func digitsToNum(d []rune) (n uint64) { if l := len(d); l > 0 { n += uint64(d[l-1] - 48) k := uint64(l - 1) for _, r := range d[:l-1] { n, k = n+uint64(r-48)*uint64(math.Pow10(k)), k-1 } } return } 

(рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдЕрдВрддрд┐рдо рдПрдХ рдирд╣реАрдВ рд╣реИ, рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдореЗрдпрд░реЛрд╡рдк рд╣рдмрд▓реНрдпреВрдЬрд╝рд░ рдиреЗ рд╕рдВрдЦреНрдпрд╛ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдФрд░ рднреА рдЕрдзрд┐рдХ рдЗрд╖реНрдЯрддрдо рддрд░реАрдХрд╛ рд╕реБрдЭрд╛рдпрд╛ рдФрд░ рдореИрдВрдиреЗ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ , рдирдП рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЗ рдЬреЛрдбрд╝реЗ рдЧрдП) ред

рдпрд╣ рдХреЛрдб рд╡рд░реНрдгреЛрдВ рдХреА рдЪреМрдбрд╝рд╛рдИ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдмрд╛рдЗрдЯреНрд╕ рдкрд░ рдкреБрдирд░рд╛рд╡реГрддрд┐ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ "unicode/utf8" рдкреИрдХреЗрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ (рдЧреЛ рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рд░рди рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ)ред рдЗрд╕рд▓рд┐рдП, рдПрдХ рдЪрдХреНрд░ рдореЗрдВ рд╣рдо рджреЛ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рд░рди рдХреЛ рдЫрд╛рдВрдЯрддреЗ рд╣реИрдВ (рдпрджрд┐ рд╡реЗ рдЕрднреА рднреА рд╡рд╣рд╛рдВ рдмрдиреЗ рд╣реБрдП рд╣реИрдВ), рдЬрдм рддрдХ рд╣рдо рджреЛрдиреЛрдВ рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рдЫреЛрд░ рддрдХ рдирд╣реАрдВ рдкрд╣реБрдВрдЪ рдЬрд╛рддреЗред рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ, рд╣рдо рдбрд┐рдЬрд┐рдЯрд▓ ASCII рд░реЗрдВрдЬ ('0' тЙд R) '9') рдореЗрдВ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрдврд╝реЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рддреНрдпреЗрдХ рд░рди рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдпрджрд┐ рдпрд╣ рдЗрд╕рдореЗрдВ рдорд┐рд▓ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рд░рдирд░ рдмрдлрд░ рдореЗрдВ рдЬрдорд╛ рдХрд░ рджреЗрддреЗ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдкрдВрдХреНрддрд┐ s1, s2 рдХрд╛ рдЕрдкрдирд╛ рд╡рд░реНрддрдорд╛рди rune r1, r2 рдФрд░ рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рдмрдлрд╝рд░ n1, n2 рд╣реИ ред рд░рди 1 рдХреА рдЪреМрдбрд╝рд╛рдИ w1, w2 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рдкрд░реНрджрд╛рдлрд╛рд╢ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдпрджрд┐ рдПрдиреНрдпреВрдорд░реЗрд╢рди рдХреЗ рд╕рдордп рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рд░рди рдореЗрдВ рд╕реЗ рдПрдХ рдЕрдВрдХ рдирд╣реАрдВ рд╣реИ, рддреЛ рджреЛрдиреЛрдВ рдореМрдЬреВрджрд╛ рдмрдлрд╝рд░ рджреЛ uint64 рдирдВрдмрд░ in1, in2 рдФрд░ рддреБрд▓рдирд╛ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред рдореИрдВ рддреБрд░рдВрдд рдзреНрдпрд╛рди рджреВрдВрдЧрд╛ рдХрд┐ рд╕реНрд╡-рдирд┐рд░реНрдорд┐рдд рдлрдВрдХреНрд╢рди digitsToNum рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ strconv.ParseUint рд╕реЗ рдЕрдзрд┐рдХ рдХреБрд╢рд▓рддрд╛ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдмрдлрд╝рд░ рдореЗрдВ рд╕рдВрдЦреНрдпрд╛рдПрдБ рд╕рдорд╛рди рд╣реИрдВ, рддреЛ рд╡рд░реНрддрдорд╛рди рд░рди рдХреА рддреБрд▓рдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ (рдЬрд╛рд╣рд┐рд░ рд╣реИ, '0' <'a', рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ r1! = R2 , рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП 'a' рдФрд░ 'a')ред

рдЬреИрд╕реЗ рд╣реА рд╣рдо рджреЛрдиреЛрдВ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЗ рдЕрдВрдд рдореЗрдВ рдкрд╣реБрдБрдЪ рдЧрдП (рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд▓рд╛рдЗрдиреЗрдВ рдЕрднреА рднреА рд╕рд╢рд░реНрдд рдмрд░рд╛рдмрд░ рд╣реИрдВ) рдФрд░ рдЗрд╕ рдХреНрд╖рдг рддрдХ рд╕рдВрдЦреНрдпрд╛ рдмрдлрд╝рд░реНрд╕ рдореЗрдВ рдХреБрдЫ рдирд┐рдХрд▓рд╛, рддреЛ рд╣рдо рдкрд░рд┐рдгрд╛рдореА рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рддреЗ рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рдЕрдВрдд рдореЗрдВ "hello123" рдФрд░ "hello124")ред рдпрджрд┐ рдЗрд╕ рдмрд╛рд░, рддрд╛рд░ рд╕рд╢рд░реНрдд рд░реВрдк рд╕реЗ рд╕рдорд╛рди рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЕрдВрддрд┐рдо рдЪрд╛рд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ - рд╣рдо рд▓рдВрдмрд╛рдИ рдХреА рдПрдХ рдХреЗрд▓реЗ рдХреА рддреБрд▓рдирд╛ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ, рдХреЗрд╡рд▓ рдЗрд╕рд▓рд┐рдП "a001" < "a00001"ред

рдкрд░реАрдХреНрд╖рдг

"рдкрд░реАрдХреНрд╖рдг рдФрд░ рдХреЛрдб рдмреЗрд╣рддрд░ рдХреЛрдб рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред"

рдореИрдВрдиреЗ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕.рдЧреЛ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдореБрдЦреНрдп рдХреЛрдб рд░рдЦрд╛, рдЗрд╕рд▓рд┐рдП рд╣рдордиреЗ рдЯреЗрд╕реНрдЯ рдХреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕_рд╕реНрдЯреЗрд╕реНрдЯ.рдЧреЛ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдбрд╛рд▓ рджрд┐рдпрд╛ред
рдкрд╣рд▓рд╛ рдкрд░реАрдХреНрд╖рдг StringLess рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рд╣реЛрдЧрд╛:

 func TestStringLess(t *testing.T) { //       //  table driven test testset := []struct { s1, s2 string //    less bool //   }{ {"aa", "ab", true}, {"ab", "abc", true}, {"abc", "ad", true}, {"ab1", "ab2", true}, {"ab1c", "ab1c", false}, {"ab12", "abc", true}, {"ab2a", "ab10", true}, {"a0001", "a0000001", true}, {"a10", "abcdefgh2", true}, {"2", "10", true}, {"2", "3", true}, {"a01b001", "a001b01", true}, {"082", "83", true}, } for _, v := range test set { if res := StringLess(v.s1, v.s2); res != v.less { t.Errorf("Compared %s to %s: expected %v, got %v", v.s1, v.s2, v.less, res) } } } 

рджреВрд╕рд░рд╛ рдкрд░реАрдХреНрд╖рдг рдпрд╣ рдЬрд╛рдВрдЪ рдХрд░реЗрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рд╕рд░рдгреА рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдмрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рд╕реЙрд░реНрдЯ, Swap , sort.Interface рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ Less рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХрд╡рд░ рдХрд░реЗрдЧрд╛ред sort.Interface рдЗрдВрдЯрд░рдлрд╝реЗрд╕ред
TestStringSort
 func TestStringSort(t *testing.T) { a := []string{ "abc1", "abc2", "abc5", "abc10", } b := []string{ "abc5", "abc1", "abc10", "abc2", } sort.Sort(Strings(b)) if !reflect.DeepEqual(a, b) { t.Errorf("Error: sort failed, expected: %v, got: %v", a, b) } } 


рдЖрдзреЗ рдШрдВрдЯреЗ рдХреЗ рдмрд╛рдж, рд╣рдорд╛рд░реЗ рд╕реНрдирд┐рдкреЗрдЯ рдХреЛ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдЕрдм рдЬреЛ рднреА рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реИ рд╡рд╣ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдЧреБрдгрд╡рддреНрддрд╛ рдХрд╛ рд╕рддреНрдпрд╛рдкрди рдХрд░ рд╕рдХреЗрдЧрд╛:

 $ go test -v -cover === RUN TestStringSort --- PASS: TestStringSort (0.00 seconds) === RUN TestStringLess --- PASS: TestStringLess (0.00 seconds) PASS coverage: 100.0% of statements ok github.com/Xlab/handysort 0.019s 

рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕рд░рд▓ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ рдЬрдм рдпрд╣ рджрд┐рдЦрд╛рдиреЗ рдХреА рдЗрдЪреНрдЫрд╛ рд╣реЛрддреА рд╣реИ рдХрд┐ рд╕рдорд╛рдзрд╛рди рдХрд╛рдлреА рдкреНрд░рднрд╛рд╡реА рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдХреЗ рдмрд╛рдж рдореИрдВрдиреЗ рдХрдИ рдмрд╛рд░ рдХреЛрдб рдХреЛ рддреЗрдЬ рдХрд┐рдпрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ regexp рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рджрд┐рдпрд╛ - рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЗрд╕рдореЗрдВ 6 рд▓рд╛рдЗрдиреЗрдВ regexp , рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдкрд░рд┐рдгрд╛рдореЛрдВ рдореЗрдВ рдиреБрдХрд╕рд╛рди рдмрд╣реБрдд рдмрдбрд╝рд╛ рдерд╛ред strconv рдФрд░ unicode.IsDigit рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рд▓рд╛рдн рдирд╣реАрдВ рд╣реБрдЖред рдЧреЛ рдХреЗ рдирд┐рдпрдорд┐рдд рд╕рд╛рдзрдиреЛрдВ рджреНрд╡рд╛рд░рд╛ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдмреЗрдВрдЪрдорд╛рд░реНрдХ, рдПрдХ рд╣реА рдлрд╛рдЗрд▓ рдореЗрдВ strings_test.go :

 func BenchmarkStringSort(b *testing.B) { //  1000   10000    : // *    3-8 ; // *    1-3 ; // *      . // 300    random seed,     //      ; //  func testSet     . set := testSet(300) // [][]string b.ResetTimer() //      // bN   for i := 0; i < bN; i++ { //       sort.Strings(set[bN%1000]) } } func BenchmarkHandyStringSort(b *testing.B) { set := testSet(300) b.ResetTimer() for i := 0; i < bN; i++ { //       sort.Sort(handysort.Strings(set[bN%1000])) } } 

рджреЛ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдФрд░ рджреЛ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдХреЗ рд╕рд╛рде рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдкреВрд░реНрдг рд╕рдВрд╕реНрдХрд░рдг:
strings_test.go
 package handysort import ( "math/rand" "reflect" "sort" "strconv" "testing" ) func TestStringSort(t *testing.T) { a := []string{ "abc1", "abc2", "abc5", "abc10", } b := []string{ "abc5", "abc1", "abc10", "abc2", } sort.Sort(Strings(b)) if !reflect.DeepEqual(a, b) { t.Errorf("Error: sort failed, expected: %v, got: %v", a, b) } } func TestStringLess(t *testing.T) { testset := []struct { s1, s2 string less bool }{ {"aa", "ab", true}, {"ab", "abc", true}, {"abc", "ad", true}, {"ab1", "ab2", true}, {"ab1c", "ab1c", false}, {"ab12", "abc", true}, {"ab2a", "ab10", true}, {"a0001", "a0000001", true}, {"a10", "abcdefgh2", true}, {"2", "10", true}, {"2", "3", true}, } for _, v := range testset { if res := StringLess(v.s1, v.s2); res != v.less { t.Errorf("Compared %s to %s: expected %v, got %v", v.s1, v.s2, v.less, res) } } } func BenchmarkStringSort(b *testing.B) { set := testSet(300) b.ResetTimer() for i := 0; i < bN; i++ { sort.Strings(set[bN%1000]) } } func BenchmarkHandyStringSort(b *testing.B) { set := testSet(300) b.ResetTimer() for i := 0; i < bN; i++ { sort.Sort(Strings(set[bN%1000])) } } // Get 1000 arrays of 10000-string-arrays. func testSet(seed int) [][]string { gen := &generator{ src: rand.New(rand.NewSource( int64(seed), )), } set := make([][]string, 1000) for i := range set { strings := make([]string, 10000) for idx := range strings { // random length strings[idx] = gen.NextString() } set[i] = strings } return set } type generator struct { src *rand.Rand } func (g *generator) NextInt(max int) int { return g.src.Intn(max) } // Gets random random-length alphanumeric string. func (g *generator) NextString() (str string) { // random-length 3-8 chars part strlen := g.src.Intn(6) + 3 // random-length 1-3 num numlen := g.src.Intn(3) + 1 // random position for num in string numpos := g.src.Intn(strlen + 1) var num string for i := 0; i < numlen; i++ { num += strconv.Itoa(g.src.Intn(10)) } for i := 0; i < strlen+1; i++ { if i == numpos { str += num } else { str += string('a' + g.src.Intn(16)) } } return str } 


рдкреИрдХреЗрдЬ рдХреЗ рд╕рднреА рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдХреЛ рдЪрд▓рд╛рдирд╛ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЪрд▓рд╛рдирд╛ рдЬрд┐рддрдирд╛ рдЖрд╕рд╛рди рд╣реИ: рдХреЗрд╡рд▓ рдлреНрд▓реИрдЧ рдФрд░ рдорд╛рд╕реНрдХ рдХреЗ рд╕рд╛рде рд░рди go test рдХрд░реЗрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдХреЗрд╡рд▓ BenchmarkHandyStringSort рдХреЛ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ, Handy рдХреЛ рдорд╛рд╕реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдо рджреЛрдиреЛрдВ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ:

 $ go test -bench=. PASS BenchmarkStringSort 500 4694244 ns/op BenchmarkHandyStringSort 100 15452136 ns/op ok github.com/Xlab/handysort 91.389s 

рдпрд╣рд╛рдВ, рд╡рд┐рднрд┐рдиреНрди рд▓рдВрдмрд╛рдИ рдХреА 10,000 рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреА рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╕рд░рдгрд┐рдпреЛрдВ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдкрд░, рдорд╛рдирд╡ рдЫрдБрдЯрд╛рдИ рд╡рд┐рдХрд▓реНрдк рдирд┐рдпрдорд┐рдд рд╕рдВрд╕реНрдХрд░рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ 3.3 рдЧреБрдирд╛ рдзреАрдорд╛ рд╕рд╛рдмрд┐рдд рд╣реБрдЖред Intel i5 1.7GHz рдкрд░ 15.6ms рдХреЗ рд▓рд┐рдП 10,000 рд▓рд╛рдЗрдиреЛрдВ рдХреА рдЫрдВрдЯрдиреА рдПрдХ рд╕реНрд╡реАрдХрд╛рд░реНрдп рдкрд░рд┐рдгрд╛рдо рд╣реИ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рдХрд╛рдо рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрджрд┐ рдХреЛрдИ рд╕рдорд╛рди рдХреЗ рд╕рд╛рде рдЖрддрд╛ рд╣реИ рдФрд░ рдЙрд╕рдХреЗ рдмреЗрдВрдЪрдорд╛рд░реНрдХ 5ms (4.7ms рдорд╛рдирдХ рдЫрдБрдЯрд╛рдИ рдХреЗ рдмрд░рд╛рдмрд░) рдХрд╛ рдкрд░рд┐рдгрд╛рдо рджрд┐рдЦрд╛рдПрдВрдЧреЗ - рд╣рд░ рдХреЛрдИ рдХреЗрд╡рд▓ рдЦреБрд╢ рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд▓рд╛рдн рдорд╛рдкрд╛ рдЬрд╛рдПрдЧрд╛ред

рдЧреЛ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╡рд┐рднрд┐рдиреНрди рдкрд╣рд▓реБрдУрдВ рдкрд░ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╕рд╛рдордЧреНрд░реА рдХреЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рд▓рд┐рдВрдХ:


рд╡рд┐рд╕реНрддрд╛рд░


рдЬрдм рд╣рдордиреЗ рдЕрдкрдиреЗ рд╕реНрдирд┐рдкреЗрдЯ рдХреЛ рдХрдВрдШреА рдХрд┐рдпрд╛, рддреЛ рдЗрд╕реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╡рд░ рдХрд┐рдпрд╛ рдФрд░ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрд╛, рдЗрд╕реЗ рд╕рдорд╛рдЬ рдХреЗ рд╕рд╛рде рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рдерд╛ред рдкреИрдХреЗрдЬ рдХрд╛ рдирд╛рдо handysort рджреНрд╡рд╛рд░рд╛ рд╕реЛрдЪрд╛ рдЧрдпрд╛ рдерд╛, рд╣реЛрд╕реНрдЯрд┐рдВрдЧ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ GitHub рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдкреВрд░рд╛ рдкреИрдХреЗрдЬ рдирд╛рдо github.com/Xlab/handysort рдорд┐рд▓рд╛ - рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдХрд╛ рдпрд╣ рддрд░реАрдХрд╛ рдкреИрдХреЗрдЬ рдирд╛рдореЛрдВ рдХреЗ рдХрд┐рд╕реА рднреА рдЯрдХрд░рд╛рд╡ рдХреЛ рд░реЛрдХрддрд╛ рд╣реИ, рд╕реНрд░реЛрддреЛрдВ рдХреА рдкреНрд░рд╛рдорд╛рдгрд┐рдХрддрд╛ рдХреА рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реИ рдФрд░ рдкреИрдХреЗрдЬ рдХреЗ рд╕рд╛рде рдЖрдЧреЗ рдХреЗ рдХрд╛рдо рдХреЗ рд▓рд┐рдП рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рд╕рдВрднрд╛рд╡рдирд╛рдПрдВ рдЦреЛрд▓рддрд╛ рд╣реИред

 . тФЬтФАтФА LICENSE тФЬтФАтФА README.md тФЬтФАтФА strings.go тФФтФАтФА strings_test.go 0 directories, 4 files 

рдПрдХ рдкреВрд░реНрдг рдШрдЯрдХ рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ of рдлрд╛рдЗрд▓реЗрдВред рдХреЛрд╢рд┐рд╢ рдХрд░реЛ, рд╢рд╛рдпрдж рдХрд┐рд╕реА рддрд░рд╣ рдХреЗ рдЬрд╛рд╡рд╛ рдШрдЯрдХ рдХреЗ рдХреЛрдб рдХреЛ рджреЗрдЦреЗрдВ:
telegram-api> src> main> java> org> telegram> api> engine> file> UploadListi.ava
- рдФрд░ рд╡рд╣ рд╕рдм рд╣реИ! рдареАрдХ рд╣реИ, рдЕрдм рд╡рд╛рдкрд╕ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред

рджреГрд╖реНрдЯрд┐рдХреЛрдг рдореИрдВ
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреИрдХреЗрдЬ рдбрд┐рдЬрд╛рдЗрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ: рдЖрдк рдЕрдкрдирд╛ рдХреЛрдб рд▓реЗрддреЗ рд╣реИрдВ, рдЯрд┐рдкреНрдкрдгреА рдХрд░рддреЗ рд╣реИрдВ, рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рд╛рде рдХрд╡рд░ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЧрд┐рдЯрд╣рдм рдкрд░ рдЕрдкрд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВред рдЕрдм рдХреЛрдИ рднреА рдЗрд╕ рдкреИрдХреЗрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рджреВрд╕рд░реЛрдВ рдХреЗ рдмреАрдЪ include рдЕрдиреБрднрд╛рдЧ рд╕реЗ рдЬреЛрдбрд╝рдХрд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ:

 import ( "bufio" "bytes" "errors" "fmt" "github.com/Xlab/handysort" "io" ) 

рдЕрд╕реЗрдВрдмрд▓реА рдХреЗ рджреМрд░рд╛рди, рд╕реНрдерд╛рдиреАрдп рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░ рдпрд╛ рдкреБрд░рд╛рдирд╛ рд╣реЛрдиреЗ рдкрд░ рдкреИрдХреЗрдЬ рд╕реНрд╡рддрдГ рд╣реА рдХрд╕ рдЬрд╛рдПрдЧрд╛ред рд▓реЗрдЦрдХ рдкреИрдХреЗрдЬ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдмрдЧ рдХреЛ рдареАрдХ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЖрдкрдХреЗ рдЙрддреНрдкрд╛рдж рдХреЛ рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ рдкреИрдХреЗрдЬ рдХреЗ рдирдП рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдпрджрд┐ рдЖрдкрдиреЗ рдирд┐рд░реНрдпрд╛рдд рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рдкрд░ рдЯрд┐рдкреНрдкрдгреА рдирд╣реАрдВ рдХреА рд╣реИ (рдкреВрдВрдЬреАрдЧрдд рдХрд╛рд░реНрдп, рдЧреИрд░-рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдЯрд┐рдкреНрдкрдгреА рдЕрдВрджрд░) рдФрд░ рдкреИрдХреЗрдЬ рдХрд╛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд┐рд╡рд░рдг рд▓рд┐рдЦрдирд╛ рди рднреВрд▓реЗрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП handysort рд╕рд╛рде:
strings.do
 // Copyright 2014 Maxim Kouprianov. All rights reserved. // Use of this source code is governed by the MIT license // that can be found in the LICENSE file. /* Package handysort implements an alphanumeric string comparison function in order to sort alphanumeric strings correctly. Default sort (incorrect): abc1 abc10 abc12 abc2 Handysort: abc1 abc2 abc10 abc12 Please note, that handysort is about 5x-8x times slower than a simple sort, so use it wisely. */ package handysort import ( "unicode/utf8" ) // Strings implements the sort interface, sorts an array // of the alphanumeric strings in decreasing order. type Strings []string func (a Strings) Len() int { return len(a) } func (a Strings) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a Strings) Less(i, j int) bool { return StringLess(a[i], a[j]) } // StringLess compares two alphanumeric strings correctly. func StringLess(s1, s2 string) (less bool) { // uint64 = max 19 digits n1, n2 := make([]rune, 0, 18), make([]rune, 0, 18) for i, j := 0, 0; i < len(s1) || j < len(s2); { var r1, r2 rune var w1, w2 int var d1, d2 bool // read rune from former string available if i < len(s1) { r1, w1 = utf8.DecodeRuneInString(s1[i:]) i += w1 // if digit, accumulate if d1 = ('0' <= r1 && r1 <= '9'); d1 { n1 = append(n1, r1) } } // read rune from latter string if available if j < len(s2) { r2, w2 = utf8.DecodeRuneInString(s2[j:]) j += w2 // if digit, accumulate if d2 = ('0' <= r2 && r2 <= '9'); d2 { n2 = append(n2, r2) } } // if have rune and other non-digit rune if (!d1 || !d2) && r1 > 0 && r2 > 0 { // and accumulators have digits if len(n1) > 0 && len(n2) > 0 { // make numbers from digit group in1 := digitsToNum(n1) in2 := digitsToNum(n2) // and compare if in1 != in2 { return in1 < in2 } // if equal, empty accumulators and continue n1, n2 = n1[0:0], n2[0:0] } // detect if non-digit rune from former or latter if r1 != r2 { return r1 < r2 } } } // if reached end of both strings and accumulators // have some digits if len(n1) > 0 || len(n2) > 0 { in1 := digitsToNum(n1) in2 := digitsToNum(n2) if in1 != in2 { return in1 < in2 } } // last hope return len(s1) < len(s2) } // Convert a set of runes (digits 0-9) to uint64 number func digitsToNum(d []rune) (n uint64) { if l := len(d); l > 0 { n += uint64(d[l-1] - 48) k := uint64(l - 1) for _, r := range d[:l-1] { n, k = n+uint64(r-48)*uint64(10)*k, k-1 } } return } 


рдЗрд╕ рддрд░рд╣ рдХреА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЛ рдЧреЛрдбреЙрдХ рдкреНрд░рд▓реЗрдЦрди рдкреНрд░рдгрд╛рд▓реА рджреНрд╡рд╛рд░рд╛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рд╛рдкреНрдд рд╣реИред рдЖрдк рдХрдИ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдкреИрдХреЗрдЬ рдкреНрд░рд▓реЗрдЦрди рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдХрдВрд╕реЛрд▓ рдореЗрдВ: godoc < > ред рдПрдХ рд╡реЗрдм рд╕реЗрд╡рд╛ рд╣реИ godoc.org рдЬреЛ рдЖрдкрдХреЛ рдХрд┐рд╕реА рднреА рдкреИрдХреЗрдЬ рдХреЗ рдкреНрд░рд▓реЗрдЦрди рдХреЛ рдЬрд▓реНрджреА рд╕реЗ рджреЗрдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ, рдЕрдЧрд░ рдпрд╣ рдкреНрд░рд╕рд┐рджреНрдз рдХреЛрдб рд╣реЛрд╕реНрдЯрд┐рдВрдЧ рд╕рд╛рдЗрдЯреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдкрд░ рд╕реНрдерд┐рдд рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдпрджрд┐ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЖрдкрдХреЗ рдХреЛрдб рдореЗрдВ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдЯрд┐рдкреНрдкрдгреА рдХреА рдЧрдИ рд╣реИ рдФрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдЬреАрдердм рдкрд░ рд╕реНрдерд┐рдд рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреИрдХреЗрдЬ рдкреНрд░рд▓реЗрдЦрди Godoc.org/github.com/Xlab/handysort рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИ (рдЖрдк рдХрд┐рд╕реА рднреА рдкреВрд░реНрдг рдкреИрдХреЗрдЬ рдХрд╛ рдирд╛рдо рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ)ред рдкреВрд░реЗ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ рдЯрд┐рдкреНрдкрдгреА рдХреА рдЬрд╛рддреА рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, godoc.org/fmt ), рдЬрдм рдкреИрдХреЗрдЬреЛрдВ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рди рдХреЗрд╡рд▓ рдЧреЛрджрд╛рдо-рджрд╕реНрддрд╛рд╡реЗрдЬреЛрдВ рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рд╕реНрд░реЛрдд рдХреЛрдб рднреА рдкрдврд╝рддрд╛ рд╣реИ, рдореИрдВ рдЗрд╕реЗ рд╕реБрдЭрд╛рддрд╛ рд╣реВрдВред

рдЫрд╡рд┐

рдЧреЛ рдХреЛрдб рдбрд┐рдЬрд╛рдЗрди рдХреЗ рд╡рд┐рднрд┐рдиреНрди рдкрд╣рд▓реБрдУрдВ рдкрд░ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╕рд╛рдордЧреНрд░реА рдХреЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рд▓рд┐рдВрдХ:

рджреГрд╖реНрдЯрд┐рдХреЛрдг II
рдпрджрд┐ рдЖрдк "GitHub рдкрд░ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рджреЛрд╕реНрдд" рдкрд░ рднрд░реЛрд╕рд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдпрд╛ рдпрджрд┐ рдЖрдкрдХреЛ рдкреИрдХреЗрдЬ рдХреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдк рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рдХрд╛рдВрдЯрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкреИрдХреЗрдЬ рдХреЛ github.com/VasyaPupkin/handysort рд░реВрдк рдореЗрдВ рдХрдиреЗрдХреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕ рдХрд╛ рд╕рд╛рд░ рдирд╣реАрдВ рдмрджрд▓реЗрдЧрд╛ред рдЙрд╕реА рд╕рдордп, рдЖрдк рдорд╛рдирд╡рддрд╛ рдХреЛ рдмрдЪрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдпрджрд┐, рдПрдХ рдареАрдХ рджрд┐рди, рдореВрд▓ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХрд╛ рд▓реЗрдЦрдХ рдкрд╣рд┐рдпреЛрдВ / рдорд╢рд░реВрдо рдХреЛ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЕрдкрдиреЗ рдкреИрдХреЗрдЬ рдХреЗ рд╕рд╛рде рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рд░реВрдк рд╕реЗ рд╣рдЯрд╛рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдХрдИ рд▓реЛрдЧреЛрдВ рдХреЗ рд╕реНрд░реЛрдд рдореЗрдВ рд╕реАрдзреЗ рд▓рд┐рдВрдХ рд╣реЛрддреЗ рд╣реИрдВред

рджреГрд╖реНрдЯрд┐рдХреЛрдг III
рдЕрдВрдд рдореЗрдВ, рдпрджрд┐ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рдирд┐рд░реНрднрд░рддрд╛ рдХрд┐рд╕реА рдФрд░ рдХреЗ рдкреИрдХреЗрдЬ рдФрд░ strings_test.go рд▓рд┐рдВрдХ рдХреА рдЬрд░реВрд░рдд рдирд╣реАрдВ рд╣реИ, рддреЛ рдЕрдкрдиреЗ рдкреИрдХреЗрдЬ рдореЗрдВ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреА рдЬрд╛рддреА рд╣реИ - рджреЛ рдлрд╛рдЗрд▓реЛрдВ strings.go рдФрд░ strings_test.go рдЕрдкрдиреЗ рдЖрдк рдХреЛ handysort.go рдФрд░ handysort_test.go ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдореБрдЦреНрдп рднрд╛рдЧ рдХреЛ рдирд╣реАрдВ рдЫреВрддреА рд╣реИ, рдФрд░ рдкрд░реАрдХреНрд╖рдг рдФрд░ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рд╕рд╛рдорд╛рдиреНрдп рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред рд╡реИрд╕реЗ, рдЧреЛ рдореЗрдВ рдХреЛрдб рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╕реНрд╡рд░реВрдкрд┐рдд рд╣реИ рдФрд░ рдЗрд╕рд▓рд┐рдП рдХрд┐рд╕реА рднреА рд╡рд┐рджреЗрд╢реА рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рдПрдХ рд╕рдордЭ рдФрд░ рд╕рд╣реА рд╢реИрд▓реА рдореЗрдВ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдПрдХ рдирд┐рд╖реНрдХрд░реНрд╖ рдХреЗ рдмрдЬрд╛рдп


рдЫрд╡рд┐
рдкреЛрд╕реНрдЯ рдХреЛ Sublime Text рдХреЗ рд▓рд┐рдП GoSublime рдкреНрд▓рдЧрдЗрди рдХреЗ рд╕рдорд░реНрдерди рд╕реЗ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рд╕рднреА рдореИрдЪ рд░реИрдВрдбрдо рд╣реИрдВред

Source: https://habr.com/ru/post/In208756/


All Articles