簡體   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