简体   繁体   English

给定一组具有2个值的对象。 相对于第一个值,然后使用第二个值对集合进行排序

[英]Given a set of objects that have 2 values. Sort the set with respect to the 1st value and then with the 2nd value

Eg.: 例如。:

{2,3},{1,2},(2,2},{3,1},{2,1} to {1,2},{2,1},{2,2},{2,3},{3,1}

Here's what I'm thinking: 这就是我的想法:

Do a merge sort on the first column of values. 对第一列值进行合并排序。 Iterate over the set to see if there are any duplicate values in the first column. 迭代集合以查看第一列中是否存在任何重复值。 If there are, enqueue them onto a list. 如果有,请将它们列入列表。

Merge sort this list on the second column and then integrate them into the main set. 合并在第二列上对此列表进行排序,然后将它们集成到主集中。 While it does seem feasible to do, it seems overly complicated. 虽然看起来确实可行,但似乎过于复杂。 This should run in O(NlogN) , so if somebody can think of a faster/same complexity algorithm that's also simpler, please post it! 这应该在O(NlogN)运行,所以如果有人能想到更快/更复杂的算法也更简单,请发布它!

Thanks! 谢谢!

Simply implement a Comparator<T> which compares any two objects of your type by first comparing the first field, and then moving on to the second field if the first fields are equal. 只需实现一个Comparator<T> ,它通过首先比较第一个字段,然后在第一个字段相等的情况下移动到第二个字段来比较您的类型的任何两个对象。 You can then copy the set into a list, call Collections.sort and give it the list and your comparator. 然后,您可以将该集复制到一个列表中,调用Collections.sort并将其列入列表和比较器。 There's no need to implement sorting yourself. 没有必要自己实现排序。

The comparator would be something like: 比较器将是这样的:

public class TwoFieldComparator implements Comparator<Foo>
{
    public int compare(Foo first, Foo second)
    {
        // TODO: null checks
        int firstComparison = Integer.compare(first.x, second.x);
        return firstComparison != 0 ? firstComparison
                                    : Integer.compare(first.y, second.y);
    }
}

Alternatively, you could make your class implement Comparable<T> in the same sort of way. 或者,您可以使您的类以相同的方式实现Comparable<T>

What you have to do is performing a stable sort on the second column then once more on the first column. 您需要做的是在第二列上执行稳定排序,然后在第一列上再次执行。

If the range of the numbers can be determined, O(N) can be achieved with some linear sort. 如果可以确定数字的范围,则可以通过某种线性排序来实现O(N)。

EDIT: 编辑:

Take 'merge sort' as an example(for it's stable): 以'merge sort'为例(因为它稳定):
1, Run a merge sort on the second column, then number pairs will be arranged according to the value of second column. 1,在第二列上运行合并排序,然后根据第二列的值排列数字对。
2, Run a merge sort again on the first column, number pairs will be arranged in the order of first column value. 2,在第一列上再次运行合并排序,数字对将按第一列值的顺序排列。 However, because the sorting method is stable, that means if the first number is the same, the second number will be sorted as well(we did it in the first sort). 但是,因为排序方法是稳定的,这意味着如果第一个数字是相同的,第二个数字也将被排序(我们在第一个排序中进行了排序)。

Thus, the num pair array is in order now. 因此,num对数组现在是有序的。 No more action is needed. 不再需要采取任何行动。
Merge sort is O(NlogN), thus 2*O(NlogN) is still O(NlogN). 合并排序为O(NlogN),因此2 * O(NlogN)仍为O(NlogN)。

EDIT2: EDIT2:
Well, I might make this problem complicated. 好吧,我可能会让这个问题变得复杂。 Even if the sorting method is needed to be implemented by our own, as long as the data stucture has been determined, filling the compare code by Jon Skeet in the corresponding part of the hand-make sorting method will be the most convenient way. 即使需要由我们自己实现排序方法,只要确定了数据结构,Jon Skeet在手工制作排序方法的相应部分填充比较代码将是最方便的方法。

As you mentioned in one of your commments, this is interview question. 正如你在其中一篇文章中提到的,这是面试问题。 Solution by John Skeet shows that you don't have to worry about having two values in your item - just implement correct comparator. John Skeet的解决方案表明,您不必担心项目中有两个值 - 只需实现正确的比较器即可。

Assuming that you are asked this at 2011, it would be good do find out how your sort is meant to be used. 假设您在2011年被问到这一点,那么最好了解您的排序是如何使用的。 Depending on environment where this sort will be used, you may consider parallel processing (using multiple threads). 根据将使用此类型的环境,您可以考虑并行处理(使用多个线程)。 That may drive your choice of sorting algorithm. 这可能会推动您选择排序算法。

暂无
暂无

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

相关问题 在更改第一微调器值时更改第二微调器值 - changing 2nd spinner values on changing 1st spinner value 在 java 中将第一个数组值乘以 1,将第二个值乘以 3 - Multiply 1st array value with 1 and 2nd value with 3 in java 在comboBox中显示对象的第一个和第二个值 - show the 1st and 2nd value of object in comboBox 以这样的方式更新 HashMap,使第二个值变成第一个,第三个变成第二个,依此类推 - Updating a HashMap in such a way that the 2nd value becomes 1st and 3rd becomes 2nd and so on 从第一页获取按钮的值,并将其回显到“模态”和第二页 - Getting the value of the button from the 1st page and echoing it to the Modal and to the 2nd page 当第二阶段对第一阶段的结果值不感兴趣时​​,完成阶段链接 - CompletionStage chaining when 2nd stage is not interested in the 1st stage result value 无法通过getIntent()将第一个活动的textview值传递给第二个活动的textview - Unable to pass 1st activity's textview value to 2nd activity's textview through getIntent() 在LDAP搜索过滤器中,是否可以要求一个多值字段的第一个,第二个,第n个或最后一个值? - In an LDAP search filter, is it possible to ask for the 1st, 2nd, nth, or last value of a multi-valued field? 如何在Java Swing中从第一个面板获取价值并插入第二个面板 - How to get value from 1st panel and insert in 2nd panel in Java Swing 在不丢失更新数据的情况下将第二个活动的价值保存到第一个活动 - Saving value from 2nd activity to 1st without losing the updated data
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM