繁体   English   中英

排序时间间隔

[英]Sorting a time intervals

我给出两个数组形式的时间间隔。

A[0]=  2  B[0]=3
A[1]=  9  B[1]=11
A[2] = 5 B[2]=6
A[3] = 3 B[3]=10

我想根据开始时间的基础对时间间隔进行排序,即

(2,3) , (3,10) ,(5,6) ,(9,11)

我是否必须对此做一个结构。 或者可以直接完成。

可以直接完成,因为您没有显示到目前为止已经尝试了什么,我只给您算法:

for j = 1 to n
    for i = i+1 to n
        if(A[i]>A[j]){
            swap(A[i],A[j])
            swap(B[i],B[j])
        }

您可以轻松地将其转换为Java代码。

如果您想获得更好的算法,则此算法是很麻烦的,请使用此Wiki 链接来缩短时间。

正如DwB想要的,这里是合并排序完整的Java代码,以执行您想要的操作。 我从这里得到了合并排序算法,并进行了修改以满足您的需求。 您也可以在Ideone上看到工作版本

合并排序:

import java.util.*;
import java.lang.*;
import java.io.*;

class Ideone
{
    private int[] A;
    private int[] B;
    private int[] helperA;
    private int[] helperB;

    private int length;

    public static void main (String[] args){
        int[] As = {2,9,5,3};
        int[] Bs = {3,11,6,10};
        new Ideone().sort(As,Bs);
    }

    public void sort(int[] As , int[] Bs) {
        A = As;
        B = Bs;
        length = A.length;
        this.helperA = new int[length];
        this.helperB = new int[length];
        mergesort(0, length - 1);
        for(int i = 0 ; i<length ; i++)
        System.out.println("(" + A[i] + "," + B[i]+  ")");
    }

    private void mergesort(int low, int high) {
        // check if low issmaller then high, if not then the array is sorted
        if (low < high) {
        // Get the index of the element which is in the middle
        int middle = low + (high - low) / 2;
        // Sort the left side of the array
        mergesort(low, middle);
        // Sort the right side of the array
        mergesort(middle + 1, high);
        // Combine them both
        merge(low, middle, high);
        }
    }

    private void merge(int low, int middle, int high) {

        // Copy both parts into the helper array
        for (int i = low; i <= high; i++) {
            helperA[i] = A[i];
            helperB[i] = B[i];
        }

        int i = low;
        int j = middle + 1;
        int k = low;
        // Copy the smallest values from either the left or the right side back
        // to the original array
        while (i <= middle && j <= high) {
            if (helperA[i] <= helperA[j]) {
                A[k] = helperA[i];
                B[k] = helperB[i];
                i++;
            } else {
                A[k] = helperA[j];
                B[k] = helperB[j];
                j++;
            }
            k++;
        }
        // Copy the rest of the left side of the array into the target array
        while (i <= middle) {
            A[k] = helperA[i];
            B[k] = helperB[i];
            k++;
            i++;
        }
    }
}

尝试:

private static class StartEnd implements Comparable<StartEnd> {
    private final int start;
    private final int end;
    // + constructor + getters
    @Override
    public int compareTo(StartEnd other) {
        return start - other.getStart();
    }
}

public void sort(int[] starts, int[] ends) {
    StartEnd[] ses = new StartEnd[starts.length];
    for(int i = 0 ; i < starts.length ; ++i) {
        ses[i] = new StartEnd(starts[i], ends[i]);
    }
    Arrays.sort(sis);
    // re-insert
    for(int i = 0 ; i < ses.length ; ++i) {
        starts[i] = ses[i].getStart;
        ends[i] = ses[i].getEnd();
    }
}

而不是拥有两个数组,创建保存间隔的对象

class Interval  implements Comparable<Interval>  {

private Long start,completed

 public Interval(Long start, Long completed) {
        this.start = start;
        this.completed = completed;
}


  @Override
  public int compareTo(Interval o) {
    return start.compareTo(o.start);
  }

//getters and setters ommited
}

然后,您所需要做的就是实现compareTo方法并将所有数据放入某个集合中,即List<Interval> intervals

并使用Collections.sort(intervals)对它们进行排序

编辑

例:

本来你有:

A[0]=  2  B[0]=3,
A[1]=  9  B[1]=11
A[2] = 5 B[2]=6
A[3] = 3 B[3]=10`

让我们替换为:

List<Interval> intervals = new ArrayList<>();
intervals.add(new Interval(2L,3L));
intervals.add(new Interval(9L,11L));
intervals.add(new Interval(5L,6L));
intervals.add(new Interval(3L,10L));
//NOTE L is added at the end variable as interval uses Long, if you change it to integer you dont need to add it;

现在您需要做的就是整理

Collection.sort(intervals);

步骤1:Java是一种面向对象的语言; 学习使用对象。

时间间隔的可能类别

public class TimeInterval implements Comparable<TimeInterval>
{
    private int end;
    private int start;

    public TimeInterval(
        final int end,
        final int start)
    {
        this.end = end;
        this.start = start;
    }

    public int getEnd()
    {
        return end;
    }

    public int getStart()
    {
        return start;
    }

    public int comareTo(final TimeInterval other)
    {
        if (other == null)
        {
            return -1; // this will put the null value objects at the end.
        }

        return start - other.start;
    }
}

对此,经典的Javanese“面向对象”方法是使用专用的类,该类存储一对值(在这种情况下为int值),并对它们进行排序,正如大多数其他答案中已经指出的那样。 但是,我建议不要使此类Comparable 相反,可以使用Comparator器,这将使引入新的排序顺序更加容易。 特别地,可能存在用于分别基于第一/第二值以升/降序排序的Comparator实现。 只有到那时,面向对象才能发挥其优势,首先弥补必须创建这样的一对int值(例如“虚拟数据结构”)的“缺点”。

但是,我也想尝试解决原始问题的解决方案,即“同步”排序两个数组。 尽管排序的任务看似微不足道,但仍可以很多工作来正确完成排序(请参阅TAOCP的第3章 )。 气泡排序很简单,但即使对于中等大小的数组也效率不高。 尝试正确获取索引时,可以轻松实现快速排序或合并排序。 但是,可以通过从java.lang.Arrays简单地采用现有的sort方法并排除最基本的构建块来获得一种解决方案: swap函数:

public class ArraySort
{
    public static void main(String[] args)
    {
        final int A[] = new int[4];
        final int B[] = new int[4];
        A[0] = 2;  B[0] = 3;
        A[1] = 9;  B[1] = 11;
        A[2] = 5;  B[2] = 6;
        A[3] = 3;  B[3] = 10;

        Swapper swapper = new Swapper()
        {
            @Override
            public void swap(int array[], int i0, int i1)
            {
                ArraySort.swap(A, i0, i1);
                ArraySort.swap(B, i0, i1);
            }
        };
        sort(A, 0, A.length, swapper);

        for (int i=0; i<A.length; i++)
        {
            System.out.println("("+A[i]+","+B[i]+")");
        }
    }

    interface Swapper
    {
        void swap(int array[], int i0, int i1);
    }

    public static void swap(int array[], int i0, int i1)
    {
        int t = array[i0];
        array[i0] = array[i1];
        array[i1] = t;
    }

    // The following methods are copied from java.util.Arrays:
    public static void sort(int x[], int off, int len, Swapper swapper)
    {
        if (len < 7)
        {
            for (int i = off; i < len + off; i++)
            {
                for (int j = i; j > off && x[j - 1] > x[j]; j--)
                {
                    swapper.swap(x, j, j - 1);
                }
            }
            return;
        }

        int m = off + (len >> 1);
        if (len > 7)
        {
            int l = off;
            int n = off + len - 1;
            if (len > 40)
            { 
                int s = len / 8;
                l = med3(x, l, l + s, l + 2 * s);
                m = med3(x, m - s, m, m + s);
                n = med3(x, n - 2 * s, n - s, n);
            }
            m = med3(x, l, m, n);
        }
        int v = x[m];

        int a = off, b = a, c = off + len - 1, d = c;
        while (true)
        {
            while (b <= c && x[b] <= v)
            {
                if (x[b] == v)
                {
                    swapper.swap(x, a++, b);
                }
                b++;
            }
            while (c >= b && x[c] >= v)
            {
                if (x[c] == v)
                {
                    swapper.swap(x, c, d--);
                }
                c--;
            }
            if (b > c)
            {
                break;
            }
            swapper.swap(x, b++, c--);
        }

        int s, n = off + len;
        s = Math.min(a - off, b - a);
        vecswap(x, off, b - s, s, swapper);
        s = Math.min(d - c, n - d - 1);
        vecswap(x, b, n - s, s, swapper);

        if ((s = b - a) > 1)
        {
            sort(x, off, s, swapper);
        }
        if ((s = d - c) > 1)
        {
            sort(x, n - s, s, swapper);
        }
    }

    private static void vecswap(int x[], int a, int b, int n, Swapper swapper)
    {
        for (int i = 0; i < n; i++, a++, b++)
        {
            swapper.swap(x, a, b);
        }
    }

    private static int med3(int x[], int a, int b, int c)
    {
        return (x[a] < x[b] ? (x[b] < x[c] ? b : x[a] < x[c] ? c : a)
            : (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
    }

}

笔记

这不是我建议的解决方案。 这只是回答问题的一种尝试

或者可以直接完成。 [太棒了!]

答案是:是的,虽然引入了某种IntPair的解决方案更惯用了,但它是可能的。

除此之外,“内联” Swapper#swap调用以直接交换存储在实例变量中或作为方法参数传递的两个数组的元素可能会更有效。 但是,我喜欢这种Swapper接口的通用性。 另外,最好通过传入类似

interface IntArrayEntryComparator {
    int compare(int array[], int i0, int i1);
}

但是后者将超出我想在本课程中进行测试/演示的范围。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM