使用比较器或多个比较器进行优先级排序?

时间:2017-08-01 01:28:17

标签: java sorting data-structures

所以我有一个大型的FlashCards LinkedList,1000张卡,用于flashcard应用程序。 有些人以前从未见过,其他人已经被人看到,并且多次正确或错误地猜对了。

有了这么多卡片,我希望那些我从来没有注意过的卡片在列表中排在第一位,其次是那些已被错过的卡片。

理想情况下,这将是一般规则而不总是正确的;我之前偶尔会看到一张卡,但其中大部分是看不见的。

此时我现在正在使用Collections.shuffle(),在上述标准中,我仍然希望卡片随机出现。

我刚刚编写了这个比较器:

public string getYear(string str)
{
    return (string)Regex.Match(str, @"\d{4}").Value;
}

var result = getYear("05/11/2010");

2010

我知道这很难!任何帮助表示赞赏。

编辑: 最后一个比较器完成了合同,我显然试图在一个比较器中做太多。如果你有几个比较器,然后做Collections.sort(x,comp1),它是如何工作的; Collections.sort(X,COMP2); Collections.sort(X,COMP3); ?

public class TimesSeenComparator implements Comparator<Card> {
    public int compare(Card one, Card two){
        boolean oneNeverSeen = false;
        boolean twoNeverSeen = false;
        if(one.getMissed() + one.getMade() == 0){ oneNeverSeen = true; }
        if(two.getMissed() + two.getMade() == 0){ twoNeverSeen = true; }
        if(oneNeverSeen && twoNeverSeen){ return 0; }

        if(one.getMissed() > two.getMissed()){
            return 1;
        } else if(one.getMissed() == two.getMissed()){
            return 0;
        } else{
            return -1;
        }
    }

}

2 个答案:

答案 0 :(得分:1)

考虑具有集合的比较器的基本示例:

Firebasenode().ref

输出结果为:

enter image description here

同样,您可以通过初始化来使用多个集合:

// Create and initialize linked list
        LinkedList ll = new LinkedList();
        ll.add(new Integer(-8));
        ll.add(new Integer(20));
        ll.add(new Integer(-20));
        ll.add(new Integer(8));
// Create a reverse order comparator
        Comparator r = Collections.reverseOrder();
// Sort list by using the comparator
        Collections.sort(ll, r);
        // Get iterator
        Iterator  li = ll.iterator();
System.out.print("List sorted in reverse: ");
while(li.hasNext())
    System.out.print(li.next() + " ");
System.out.println();
Collections.shuffle(ll);
// display randomized list
li = ll.iterator();
System.out.print("List shuffled: ");
while(li.hasNext())
    System.out.print(li.next() + " ");
System.out.println();
System.out.println("Minimum: " + Collections.min(ll));
System.out.println("Maximum: " + Collections.max(ll));

并通过迭代器访问它。它取决于你想要使用的方法。我在这里使用reverseOrder()但你可以根据你的逻辑使用。我希望这会对你有所帮助。 谢谢!

答案 1 :(得分:0)

我不知道你为比较器做了什么,所以我将回答这个问题:

  

有了这么多卡片,我希望那些我从未注意过的卡片在列表中排在第一位,其次是那些已经错过的卡片,而不是被钉死的卡片。

     

理想情况下,这将是一般规则而不总是正确的;我之前偶尔会看到一张卡,但其中大部分是看不见的。

以下代码将执行您想要的操作:

List<Card> cards;

List<Card> neverSeen = new ArrayList<>();
List<Card> missedMore = new ArrayList<>();
List<Card> other = new ArrayList<>();

for (Card card : cards) {
    if (card.getMade() == 0 && card.getMissed() == 0) {
        neverSeen.add(card);
    } else if (card.getMissed() > card.getMade()) {
        // Add about 1 in 10 to the beginning
        if (Math.random() < 0.1) {
            neverSeen.add(card);
        } else {
            missedMore.add(card);
        }
    } else {
        // Add about 1 in 20 to the beginning
        if (Math.random() < 0.05) {
            neverSeen.add(card);
        } else {
            other.add(card);
        }
    }
}

Collections.shuffle(neverSeen);
Collections.shuffle(missedMore);
Collections.shuffle(other);

neverSeen.addAll(missedMore);
neverSeen.addAll(other);

cards = neverSeen;
笔记:
  • Collections.sort(X,COMP1); Collections.sort(X,COMP2); Collections.sort(X,COMP3);
    与Collections.sort(x,comp3)相同;
    如果您想使用多个比较器,可以使用ComparatorChain
    或java 8 Comparator.comparing.thenComparing
  • 使用ArrayList比使用LinkedList
  • 几乎总是更好(更快)