按字典顺序对int数组进行排序

时间:2013-12-04 13:54:04

标签: java sorting

我遇到了一个问题:

  

WAP按数字对小于给定N的素数进行排序。如果N是40,   输出应为11,13,17,19,2,23,29,3,31,37,39,5,7。   注意:限制内存使用。

获取主号码很容易。但我无法找到一种有效的整数数组排序方法。

public static void getPrimeNumbers(int limit) {
        for (int i=2; i<=limit; i++) {
            if(isPrime(i)) {
                System.out.println(i);
            }
        }
    }

    public static boolean isPrime(int number) {
        for(int j=2; j<number; j++) {
            if(number%j==0) {
                return false;
            }
        }
            return true;
    }

    public static void lexographicSorting() {
        int[] input = {2,3,5,7,11,13,17,19};
        int[] output = {};
        for (int i=0; i<input.length; i++) {
            for(int j=0; j<input.length; j++) {
                ////Stuck at this part.
            }
        }
    }

5 个答案:

答案 0 :(得分:3)

Java String#compareTo已实现此功能,您可以通过将Integer对象转换为String对象并调用compareTo

来轻松访问它
Arrays.sort(input, new Comparator<Integer>() {
   @Override
   int compareTo( Integer x, Integer y ) {
      return x.toString().compareTo( y.toString() );
   }
};

我可以确切地说这将是多少内存效率,你必须为数组中的每个原语int创建1个Integer对象,然后你必须为你拥有的每个Integer对象创建1个String对象。因此,对象创建可能会产生大量开销。

答案 1 :(得分:2)

唯一可能的方法是实现您自己的Comparator,您可以将两个可比较的Integer - s中的每一个转换为String个对象并对其进行比较。

UPD:以下是一个示例,如何实现它:

    Integer[] input = {2,3,5,7,11,13,17,19};

    Arrays.sort(input, new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o1.toString().compareTo(o2.toString());
        }
    });

答案 2 :(得分:2)

考虑到问题的限制,解决此问题的更有效方法是根本不使用String和Integer实例。该问题的一个指令是限制内存使用。在目前为止的每个答案中,对内存产生了重大影响(转换为IntegerString

这是一个可能更快的解决方案,并且根本不分配堆内存(尽管它具有递归,因此它可能具有一些堆栈效果 - 与Arrays.sort()大致相同)。这解决了第一原理的问题,它没有为结果分配单独的数组,因此,与其他解决方案相比,它相对较长,但是,那些其他解决方案隐藏了该解决方案所没有的大量复杂性。

// this compare works by converting both values to be in the same 'power of 10',
// for example, comparing 5 and 20, it will convert 5 to 50, then compare 50 and 20
// numerically.
public static final int compareLexographicallyToLimit(final int limit, int a, int b) {
    if (a == b) {
        return 0;
    }
    if (a > limit || b > limit || a < 0 || b < 0) {
        return a > b ? 1 : -1;
    }

    int max = Math.max(a, b);
    int nextp10 = 1;
    while (max > 10) {
        max /= 10;
        nextp10 *= 10;
    }
    while (a < nextp10) {
        a *= 10;
    }
    while (b < nextp10) {
        b *= 10;
    }
    return a > b ? 1 : -1;
}

private static void sortByRules(final int[] input, final int limit, final int from, final int to) {
    if (from >= to) {
        return;
    }
    int pivot = from;
    int left = from + 1;
    int right = to;
    while (left <= right) {
        while (left <= right && compareLexographicallyToLimit(limit, input[left], input[pivot]) <= 0) {
            left++;
        }
        while (left <= right && compareLexographicallyToLimit(limit, input[pivot], input[right]) <= 0) {
            right--;
        }
        if (left < right) {
            int tmp = input[left];
            input[left] = input[right];
            input[right] = tmp;
            left++;
            right--;
        }
    }
    int tmp = input[pivot];
    input[pivot] = input[right];
    input[right] = tmp;
    sortByRules(input, limit, from, right-1);
    sortByRules(input, limit, right+1, to);

}

public static void main(String[] args) {
    int[] input = {2,3,5,7,11,13,17,19,31,37,41, 43, 100};
    sortByRules(input, 40, 0, input.length - 1);
    System.out.println(Arrays.toString(input));
    sortByRules(input, 15, 0, input.length - 1);
    System.out.println(Arrays.toString(input));
}

答案 3 :(得分:0)

如果您不想将整数值转换为字符串(这可能会浪费),您可以执行以下操作。

您可以根据最高位数对数字进行排序。请参阅此文章以计算数字中最重要的数字:Getting a values most significant digit in Objective C(应该很容易移植到Java)。

基本上,您可以将该功能用作比较器的一部分。你需要一种方法来打破关系(例如,具有相同最高位数的数字)。如果两个数字具有相同的最高有效数字,您可以将它们摘下并根据需要反复重复调用此函数(直到您可以认为一个数字大于另一个数字,或直到您的数字用完为止,表明他们是平等的。

答案 4 :(得分:0)

为了补充Hunter McMillen的答案,Java 8的语法允许以更清洁,更精简的方式定义Comnparator。由于Arrays.sort(int[]) 的重载变体需要Comparator,因此需要装箱数组才能使用Comparator。 E.g:

int[] output =
    Arrays.stream(input)
          .boxed()
          .sorted(Comparator.comparing(String::valueOf))
          .mapToInt(Integer::intValue)
          .toArray();