Сравнить и отсортировать строки Java - PullRequest
3 голосов
/ 21 апреля 2019

У меня есть массив строк: 15 МБ, 12 МБ, 1 ТБ, 1 ГБ. Я хочу сравнить их лексикографически, просто следуя правилу, что МБ меньше, чем ГБ и ТБ. Итак, в конце я хочу получить: 12 МБ, 15 МБ, 1 ГБ, 1 ТБ. Я нашел способ сравнить буквы:

 final static String ORDER="MGT";

public int compare(String o1, String o2) {
       int pos1 = 0;
       int pos2 = 0;
       for (int i = 0; i < Math.min(o1.length(), o2.length()) && pos1 == pos2; i++) {
          pos1 = ORDER.indexOf(o1.charAt(i));
          pos2 = ORDER.indexOf(o2.charAt(i));
       }

       if (pos1 == pos2 && o1.length() != o2.length()) {
           return o1.length() - o2.length();
       }

       return pos1  - pos2  ;
    }

Я думаю о том, чтобы разбить строку по номерам и буквам, но как мне отсортировать их по буквам "МБ ...", а затем по их номерам. Я использую два компаратора или что-то еще?

Ответы [ 3 ]

1 голос
/ 22 апреля 2019

будет намного проще сравнивать, если вы сначала преобразуете данные в общую единицу (например, МБ). если значения после этого преобразования совпадают, то вам следует применить лексикографическую сортировку, это может выглядеть так:

private int convertToMegaBytes(String s) {

    char c = s.charAt(s.length() - 2);

    if(c == 'G')
        return 1024 * Integer.parseInt(s.substring(0, s.length() - 2));
    if(c == 'T')
        return 1024 * 1024 * Integer.parseInt(s.substring(0, s.length() - 2));

    return Integer.parseInt(s.substring(0, s.length() - 2));

}

final static String ORDER = "MGT";

public int compare(String o1, String o2) {
    int v = convertToMegaBytes(o1)  - convertToMegaBytes(o2);
    // if values are equal then compare lexicographically
    return v == 0 ? ORDER.indexOf(o1.charAt(o1.length() - 2)) - ORDER.indexOf(o2.charAt(o2.length() - 2)) : v;
}
0 голосов
/ 22 апреля 2019

Теперь сортируется сначала по единицам, а затем по значениям в единицах. Это было изменено, чтобы отразить последний комментарий ОП.

import java.util.*;

enum Memory {
   B(1), KB(2), MB(3), GB(4), TB(5);
   public long val;

   private Memory(long val) {
      this.val = val;
   }
}

public class MemorySort {
   public static void main(String[] args) {
      List<String> memory = Arrays.asList("122003B",
            "1TB",
            "2KB",
            "100000MB",
            "1027MB",
            "2024GB");

      Comparator<String> units = Comparator.comparing(
            a -> Memory.valueOf(a.replaceAll("\\d+", "")).val);

      Comparator<String> values = Comparator.comparing(
            a -> Integer.parseInt(a.replaceAll("[A-Z]+", "")));

      Collections.sort(memory, units.thenComparing(values));
      System.out.println(memory);
   }
}


0 голосов
/ 22 апреля 2019

Это может помочь.Метод compare получает количество байтов, которое каждая строка представляет как длинный (10 КБ становится 10000), а затем сравнивает их.Метод getSizeOfString превращает String в long, который представляет число байтов, которые он представляет.

  public int compare(String o1, String o2) {
    long size1 = getSizeOfString(o1);
    long size2 = getSizeOfString(o2);
    return Long.compare(size1, size2);
  }

  private long getSizeOfString(String sizeString) {
    Pattern validSizePattern = Pattern.compile("(\\d+)([KMG])B");
    Matcher matcher = validSizePattern.matcher(sizeString);
    matcher.find();
    long size = Long.valueOf(matcher.group(1));

    switch (matcher.group(2)) {
      case "K":
        size *= 1024;
        break;
      case "M":
        size *= (1024 * 1024);
        break;
      case "G":
        size *= (1024 * 1024 * 1024);
        break;
    }
    return size;
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...