Табигый сорттоо тартибинде башаламандык

Көпчүлүк графикалык файл менеджерлери лексикографиялык түрдө сорттошпойт, тескерисинче, "табигый" сорттоону колдонушат. Аттардагы сандардын блоктору сандар катары чечмеленет — алфавит боюнча карама-каршы болсо дагы, чоңураак сан блогу жеңет. Табигый сорттоо идеясы: Адамдар адатта "10го чейин 9", "10-бөлүмгө чейин 2-бөлүм" - алдыңкы нөлдөрдү кошпостон.


Төмөнкү файл жуптары табигый түрдө төмөнкүдөй өсүү тартибинде иреттелген:

  • build-9e2.log
  • build-950.log

Укмуштуудай, бирок түшүнүктүү: \(9\) биринчи цифрасы \(950\) цифраларынын биринчи блогунан кичине.

  • IMG_12113419_90.jpg
  • IMG_0554363070_90.jpg

\(12113419\) саны \(554363070\) азыраак (башкы \(0\) алынып салынган).

  • temp_0C.txt
  • temp_2C.txt
  • temp_-3C.txt
  • temp_10C.txt
  • temp_-12C.txt

Салыштырылган сандар \(0\) , \(2\) , \(3\) , \(10\) , \(12\) – “-” сандын бир бөлүгү болуп эсептелбейт.

Жада калса "алфавиттик" да глобалдуу түрдө бир мааниге ээ эмес: баш тамгалар, ä (немецче) сыяктуу умлауттар же ch (чех) сыяктуу көп белгиден турган тамгалар мыйзамдуу варианттарга алып келет. Демек, "таза алфавиттик" контекстке көз каранды. Windows Explorer муну StrCmpLogicalW функциясында ишке ашырат. Анын баштапкы коду (shlwapi.dll) ачык эмес, менчик болуп саналат, бирок, мисалы, ReactOS'тун реимплементтери бар.:

{
    TRACE("%s, %s\n", wine_dbgstr_w(str), wine_dbgstr_w(comp));
 
    if (!str || !comp)
        return 0;
 
    while (*str)
    {
        if (!*comp)
            return 1;
        else if (*str >= '0' && *str <= '9')
        {
            int str_value, comp_value;
 
            if (*comp < '0' || *comp > '9')
                return -1;
 
            /* Compare the numbers */
            StrToIntExW(str, 0, &str_value);
            StrToIntExW(comp, 0, &comp_value);
 
            if (str_value < comp_value)
                return -1;
            else if (str_value > comp_value)
                return 1;
 
            /* Skip */
            while (*str >= '0' && *str <= '9') str++;
            while (*comp >= '0' && *comp <= '9') comp++;
        }
        else if (*comp >= '0' && *comp <= '9')
            return 1;
        else
        {
            int diff = ChrCmpIW(*str, *comp);
            if (diff > 0)
                return 1;
            else if (diff < 0)
                return -1;
 
            str++;
            comp++;
        }
    }
 
    if (*comp)
      return -1;
 
    return 0;
}

Google Drive, OneDrive, KDE жана башкалар окшош сорттоо жүрүм-турумун көрсөтөт. сыяктуу CLI куралдары ls жана find Бирок, алар GUI файл менеджерлеринен башкача сорттошот. Семантика APIде эмес, файл аталыштарында. Эгер сиз күтүлбөгөн жыйынтыктарды кааласаңыз, конвенцияларды аныктаңыз: ырааттуу бөлгүчтөр, толтурулган сандар жана бирдиктерди так иштетүү. Андан кийин "алфавиттик" кайра болжолдуу болуп калат.

Артка