Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有比较器和交换功能的java排序_Java_Sorting - Fatal编程技术网

带有比较器和交换功能的java排序

带有比较器和交换功能的java排序,java,sorting,Java,Sorting,我需要排序功能与自定义比较器和交换功能。我可以自己写一本,但我想知道是否有人还没有写过。Java运行时包含许多专门的排序函数,用于对基元类型、对象等的数组进行排序,但没有一个将swap函数作为参数。谷歌搜索也没有发现任何有用的东西 public interface IntComparator { int compare(int a, int b); } public interface IntSwap { void swap(int a, int b); } public sta

我需要排序功能与自定义比较器和交换功能。我可以自己写一本,但我想知道是否有人还没有写过。Java运行时包含许多专门的排序函数,用于对基元类型、对象等的数组进行排序,但没有一个将swap函数作为参数。谷歌搜索也没有发现任何有用的东西

public interface IntComparator
{
    int compare(int a, int b);
}
public interface IntSwap
{
    void swap(int a, int b);
}
public static void sort(IntComparator compFn, IntSwap swapFn, int off, int len);

我需要在两个数组中交换索引。我知道我可以对二维数组进行排序,但这会增加所需的内存。

不。如果我理解正确,这不会导致任何开销

请记住,Java不会将数组或对象直接存储在变量(或数组!)中。它存储引用。即使从数组中引用的每个元素都有40字节大,它也将作为引用存储在数组中

因此,我建议您使用内置的排序机制。它们不会在大量数据中移动,只会在引用中移动。

因为对于
对象的数组来说是稳定的,您可以在自定义
比较器中获得有用的信息。这一个在按
字符串
长度排序时对掉期进行计数

import java.util.Arrays;
import java.util.Comparator;

/** @see http://stackoverflow.com/questions/4983746 */
public class SortTest {

    private static class LengthComparator implements Comparator<String> {

        private int count;

        public int compare(String s1, String s2) {
            int a = s1.length();
            int b = s2.length();
            if (a < b) {
                return -1;
            } else if (a > b) {
                count++;
                return 1;
            } else {
                return 0;
            }
        }
    }

    public static void main(String[] args) throws Exception {
        String[] sa = {"One", "Two", "Three", "Four", "Five"};
        System.out.println(Arrays.toString(sa));
        LengthComparator byLength = new LengthComparator();
        Arrays.sort(sa, byLength);
        System.out.println(Arrays.toString(sa));
        System.out.println(byLength.count);
    }
}
导入java.util.array;
导入java.util.Comparator;
/**@见http://stackoverflow.com/questions/4983746 */
公共类分类测试{
私有静态类LengthComparator实现Comparator{
私人整数计数;
公共整数比较(字符串s1、字符串s2){
int a=s1.length();
int b=s2.length();
if(ab){
计数++;
返回1;
}否则{
返回0;
}
}
}
公共静态void main(字符串[]args)引发异常{
字符串[]sa={“一”、“二”、“三”、“四”、“五”};
System.out.println(Arrays.toString(sa));
LengthComparator byLength=新的LengthComparator();
Arrays.sort(sa,byLength);
System.out.println(Arrays.toString(sa));
系统输出打印项次(长度计数);
}
}
控制台:

[One, Two, Three, Four, Five] [One, Two, Four, Five, Three] 2 [一,二,三,四,五] [一,二,四,五,三] 2.
关于交换:Java按值传递参数,因此方法
swap(int a,int b)
swap(Object a,Object b)
不能按预期工作。

如果您提出这些接口,至少对它们应该做的事情添加一些注释。从讨论中我发现你想要这样的东西:

/**
 * A Sortable represents a indexed collection of comparable
 * elements.
 * It does not offer direct access to its elements, only
 * comparison and swapping by indices.
 *
 * In the method specifications we are using this[i] to
 * mean the 
 */
public interface Sortable {

    /**
     * Compares two elements by their indices.
     * @return -1 if this[first] < this[second],
     *          0 if this[first] = this[second]
     *          1 if this[first] > this[second]
     * @throws IndexOutOfBoundsException if one
     *      or both indices are outside of the
     *      limits of this sequence.
     */
    public int compare(int first, int second);

    /**
     * Swaps two elements by their indices.
     * This is roughly equivalent to this sequence:
     * <pre>
     *   temp = this[first];
     *   this[first] = this[second];
     *   this[second] = temp;
     * </pre>
     */
    public void swap(int first, int second);

}

interface Sorter {
   /**
    * sorts an interval of a sequence.
    * @param sequence the sequence to be sorted.
    * @param off the start of the interval to be sorted.
    * @param the length of the interval to be sorted.
    */
   public void sort(Sortable sequence, int off, int len);
}
/**
*可排序表表示可比较数据的索引集合
*元素。
*它不提供对其元素的直接访问,只是
*通过索引进行比较和交换。
*
*在方法规范中,我们使用此[i]来
*意思是
*/
公共接口可排序{
/**
*通过索引比较两个元素。
*@return-1如果此[第一]<此[第二],
*如果此[第一]=此[第二]
*1如果此[第一]>此[第二]
*@如果存在IndexOutOfBoundsException,则抛出IndexOutOfBoundsException
*或者这两个指数都超出了标准
*这个序列的极限。
*/
公共整数比较(整数第一,整数第二);
/**
*按指数交换两个要素。
*这大致相当于以下顺序:
* 
*temp=这个[第一个];
*这个[第一]=这个[第二];
*这[秒]=温度;
* 
*/
公共无效掉期(整数第一,整数第二);
}
接口分拣机{
/**
*对序列的间隔进行排序。
*@param sequence要排序的序列。
*@param关闭要排序的间隔的开始。
*@param要排序的间隔的长度。
*/
公共无效排序(可排序序列、int off、int len);
}
然后您可以让您的排序算法实现
Sorter
,而您的数据结构实现
Sortable

当然可以在
IndexComparator
IndexSwapper
中拆分Sortable的两个函数(不是Int…像您命名的那样),但它们都直接耦合到您的数据结构(由两个数组组成)。

这就是我想要的。它基于用于排序整数的java运行时算法。通过正确实现可排序接口,它可以对任何内容进行排序

公共类排序{ 公共静态无效排序(可排序、int off、int len){ //最小数组的插入排序 if(len<7){ for(int i=off;ioff&&sortable.compare(j-1,j)>0;j--){ 可排序交换(j,j-1); } } 返回; }

//选择一个分区元素,v
int m=off+(len>>1);//小数组,中间元素
如果(len>7){
int l=关;
int n=关+长-1;
如果(len>40){//大数组,则伪数为9
int s=len/8;
l=med3(可排序,l,l+s,l+2*s);
m=med3(可排序,m-s,m,m+s);
n=med3(可排序,n-2*s,n-s,n);
}
m=med3(可排序,l,m,n);//中等大小,med/3
}
//建立不变量:v*(v)*v*
int a=off,b=a,c=off+len-1,d=c;
while(true){
while(b=0){
if(可排序比较(c,m)==0){
可排序交换(c,d);
m=d;
d--;
}
c--;
}
如果(b>c){
打破
}
swap(b++,c--);
}
//将分区元素交换回中间位置
int s,n=关+长;
s=数学最小值(a-off,b-a);
矢量交换(可排序、关闭、b-s、s);
s=数学最小值(d-c,n-d-1);
向量交换(可排序,b,n-s,s);
//递归排序非分区元素
如果((s=b-a)>1){
排序(可排序、关闭、s);
}
如果((s=d-c)>1){
public class Sort {
    public static void sort(Sortable sortable, int off, int len) {
        // Insertion sort on smallest arrays
        if (len < 7) {
            for (int i = off; i < len + off; i++) {
                for (int j = i; j > off && sortable.compare(j - 1, j) > 0; j--) {
                    sortable.swap(j, j - 1);
                }
            }
            return;
        }

    // Choose a partition element, v
    int m = off + (len >> 1); // Small arrays, middle element
    if (len > 7) {
        int l = off;
        int n = off + len - 1;
        if (len > 40) { // Big arrays, pseudomedian of 9
            int s = len / 8;
            l = med3(sortable, l, l + s, l + 2 * s);
            m = med3(sortable, m - s, m, m + s);
            n = med3(sortable, n - 2 * s, n - s, n);
        }
        m = med3(sortable, l, m, n); // Mid-size, med of 3
    }

    // Establish Invariant: v* (<v)* (>v)* v*
    int a = off, b = a, c = off + len - 1, d = c;
    while (true) {
        while (b <= c && sortable.compare(b, m) <= 0) {
            if (sortable.compare(b, m) == 0) {
                sortable.swap(a, b);
                m = a;
                a++;
            }
            b++;
        }
        while (c >= b && sortable.compare(c, m) >= 0) {
            if (sortable.compare(c, m) == 0) {
                sortable.swap(c, d);
                m = d;
                d--;
            }
            c--;
        }
        if (b > c) {
            break;
        }
        sortable.swap(b++, c--);
    }

    // Swap partition elements back to middle
    int s, n = off + len;
    s = Math.min(a - off, b - a);
    vecswap(sortable, off, b - s, s);
    s = Math.min(d - c, n - d - 1);
    vecswap(sortable, b, n - s, s);

    // Recursively sort non-partition-elements
    if ((s = b - a) > 1) {
        sort(sortable, off, s);
    }
    if ((s = d - c) > 1) {
        sort(sortable, n - s, s);
    }
}

private static int med3(Sortable sortable, int a, int b, int c) {
    return sortable.compare(a, b) < 0 ? (sortable.compare(b, c) < 0 ? b : sortable.compare(a, c) < 0 ? c : a)
            : sortable.compare(b, c) > 0 ? b : sortable.compare(a, c) > 0 ? c : a;
}

private static void vecswap(Sortable sortable, int a, int b, int n) {
    for (int i = 0; i < n; i++, a++, b++) {
        sortable.swap(a, b);
    }
}