简体   繁体   English

排序时间间隔

[英]Sorting a time intervals

I am giving a time interval in the form of two arrays. 我给出两个数组形式的时间间隔。

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

I want to sort the interval on the basics of starting time ie 我想根据开始时间的基础对时间间隔进行排序,即

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

Does i have to make a structure of this. 我是否必须对此做一个结构。 or it can be done straight. 或者可以直接完成。

It can be done straight, since you dont show what have you tried so far I just give you the algorithm: 可以直接完成,因为您没有显示到目前为止已经尝试了什么,我只给您算法:

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])
        }

you can easily convert it to java code. 您可以轻松地将其转换为Java代码。

this algorithm is buble sort if you want better algorithm use this wiki link to improve your time. 如果您想获得更好的算法,则此算法是很麻烦的,请使用此Wiki 链接来缩短时间。

As DwB want here is merge sort full java code that do what you want. 正如DwB想要的,这里是合并排序完整的Java代码,以执行您想要的操作。 I got merge sort algorithm from here and modify to satisfy your need. 我从这里得到了合并排序算法,并进行了修改以满足您的需求。 also you could see the working version on Ideone 您也可以在Ideone上看到工作版本

Merge Sort: 合并排序:

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++;
        }
    }
}

Try: 尝试:

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();
    }
}

instead having two arrays, create object which holds your intervals 而不是拥有两个数组,创建保存间隔的对象

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
}

then, all what you need to do is implement compareTo method and put all your data in some collection ie List<Interval> intervals 然后,您所需要做的就是实现compareTo方法并将所有数据放入某个集合中,即List<Interval> intervals

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

EDIT 编辑

Example: 例:

originally you have: 本来你有:

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

lets replace this by: 让我们替换为:

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;

And now all what you need to do is sort 现在您需要做的就是整理

Collection.sort(intervals);

Step 1: Java is an object oriented language; 步骤1:Java是一种面向对象的语言; learn to use objects. 学习使用对象。

Possible class for the time interval 时间间隔的可能类别

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;
    }
}

The classical Javanese "object oriented" approach for this is to use a dedicated class storing a pair of values ( int values, in this case), and sort them, as already pointed out in most of the other answers. 对此,经典的Javanese“面向对象”方法是使用专用的类,该类存储一对值(在这种情况下为int值),并对它们进行排序,正如大多数其他答案中已经指出的那样。 However, I'd recommend to not make this class Comparable . 但是,我建议不要使此类Comparable Instead, a Comparator could be used, which would make it much easier to introduce new sorting orders. 相反,可以使用Comparator器,这将使引入新的排序顺序更加容易。 Particularly, there could be Comparator implementations for sorting in ascending/descending order, based on the first/second value, respectively. 特别地,可能存在用于分别基于第一/第二值以升/降序排序的Comparator实现。 Only then, object orientation plays out its advantages, compensating the "disadvantage" of having to create such a pair of int values as a "dummy data structure" in the first place... 只有到那时,面向对象才能发挥其优势,首先弥补必须创建这样的一对int值(例如“虚拟数据结构”)的“缺点”。

However, I wanted to try to find a solution for the original question as well, namely, sorting two arrays "in sync". 但是,我也想尝试解决原始问题的解决方案,即“同步”排序两个数组。 Despite the task of sorting seemingly being trivial, one can dedicate a lot of work to doing it right (see Chapter 3 of TAOCP ). 尽管排序的任务看似微不足道,但仍可以很多工作来正确完成排序(请参阅TAOCP的第3章 )。 A bubble sort is simple but inefficient even for medium-sized arrays. 气泡排序很简单,但即使对于中等大小的数组也效率不高。 Implementing a quick- or merge sort can be fiddly when trying to get the indices right. 尝试正确获取索引时,可以轻松实现快速排序或合并排序。 However, one solution can be obtained by simply taking the existing sort method from java.lang.Arrays , and factoring out the most elementary building block: The swap function: 但是,可以通过从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));
    }

}

Notes 笔记

This is not a solution that I would recommend. 这不是我建议的解决方案。 It's just an attempt to answer the question 这只是回答问题的一种尝试

or it can be done straight. 或者可以直接完成。 [sic!] [太棒了!]

And the answer is: Yes, it is possible, although the solutions that are introducing some sort of an IntPair are more idiomatic. 答案是:是的,虽然引入了某种IntPair的解决方案更惯用了,但它是可能的。

Apart from that, it would probably be more efficient to "inline" the Swapper#swap calls to directly swap elements of two arrays that are stored in instance variables, or passed as method parameters. 除此之外,“内联” Swapper#swap调用以直接交换存储在实例变量中或作为方法参数传递的两个数组的元素可能会更有效。 However, I liked the genericity of such a Swapper interface. 但是,我喜欢这种Swapper接口的通用性。 Additionally, it would be nice to generalize this even further, by passing in something like a 另外,最好通过传入类似

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

But the latter would go beyond what I wanted to test/demonstrate with this class. 但是后者将超出我想在本课程中进行测试/演示的范围。

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

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