繁体   English   中英

使用自定义排序算法对卡片组进行排序

[英]Sorting deck of Cards using custom sorting algorithms

我试图在一副牌上实现不同的排序算法。 我已经使用枚举实现了一个基卡类来构建套装和面孔。 我的班级基于Dietel和Dietel的Java Book。 但是,我正在努力将卡片传递到我实现的排序算法中,因为我无法传递一个我可以排序的数组。 我不知道我的方法是否正确,我已经阅读了stackexchange上的许多帖子,其中一些人建议使用Comparable( 在Java中实现一个卡片组 ),我看不到使用我的排序算法。 请参阅( 如何对卡片进行排序。(我的代码是否错误?) )和( 在Java中实现卡片组 )和( ArrayList中的Java排序对象 )。 通过让DeckOfCards返回一系列数字,例如1.1,1.2,1.3,我想我有一个可以排序的序列。 我也读过关于序数的文章,但对这些文章的所有评论似乎都反对这种方法。 感谢您对此尝试的任何帮助。 请注意,我已经以相同的方式实现了合并排序和选择排序以及同样的问题 - 我在这里显然遗漏了一些东西!

以下是我的代码:

//卡类

class Card
{    
     //public static enum Face {Ace, Deuce, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King};
     public static enum Face {Ace(1), King(2), Queen(3), Jack(4), Ten(5), Nine(6), Eight(7), Seven(8), Six(9), Five(10), Four(11), Three(12), Deuce(13);
     int rank;
     Face(int r){ rank = r;}
     int getRank() {return rank;}
}
//public static enum Suit {Clubs, Diamonds, Hearts, Spades };
public static enum Suit {Spades(1), Hearts(2), Diamonds(3), Clubs(4);
   int order;
   Suit(int o){ order = o;}
   int getOrder() {return order;}
}

private final Face face; // face of card
private final Suit suit; // suit of card

// two-argument constructor
public Card( Face cardFace, Suit cardSuit ) 
{   
    face = cardFace; // initialize face of card
    suit = cardSuit; // initialize suit of card
}

// return face of the card
public Face getFace() { return face;}

// return suit of Card
public Suit getSuit() { return suit;}

// return String representation of Card
public String toString()
{
   //return String.format( "%s.%s", suit.getOrder(), face.getRank() );
   return String.format( "%s.%s", suit, face );
}
}

 // class DeckOfCards declaration
 public class DeckOfCards 
{
   private List< Card > list; // declare List that will store Cards

   // set up deck of Cards and shuffle
   public DeckOfCards()
  {
     Card[] deck = new Card[ 52 ];
     int count = 0; // number of cards

     // populate deck with Card objects
     for ( Card.Suit suit : Card.Suit.values() )  
     {
         for ( Card.Face face : Card.Face.values() )   
        {
            deck[ count ] = new Card( face.getRank(), suit.getOrder() );
            count++;
        }
     }

     list = Arrays.asList( deck ); // get List
     //Collections.shuffle( list );  // shuffle deck
   }

   // output deck
   public void printCards()
  {
      // display 52 cards in two columns
      for ( int i = 0; i < list.size(); i++ )
      System.out.printf( "%-20s%s", list.get( i ),
          ( ( i + 1 ) % 2 == 0 ) ? "\n" : "" );
  }

  public static void main( String[] args )
 {
     DeckOfCards cards = new DeckOfCards();
     cards.printCards();
    //cards.InsertionSort();    
 }
 }

//插入排序

public static void insertionSort(DeckOfCards[] listToSort) 
{
    for (int i = 0; i < listToSort.length-1; i++) 
    {
        for (int k = i+1; k>0; k--) 
       {
           if(listToSort[k] < listToSort[k-1]) //Code breaks here
           {
                swap(listToSort, k, k-1);
            }
            else 
            {
                break;
            }
            print(listToSort);
        }
    }
}

问题是listToSort[k] < listToSort[k-1]正在尝试使用<运算符比较两个DeckOfCards对象,这在Java中是不允许的 - 请参阅: 将两个对象与Java中的运算符进行比较


正如该帖子指出的那样,你应该使用Comparator作为Card对象。

public class CardComparator implements Comparator<Card> {
    @Override
    public int compare(Card o1, Card o2) {
        // ...
        // Use Card.getFace().getRank() and Card.getSuit().getOrder()
        // ...
    }
}

在你的DeckOfCards类中,我还建议添加一个方法,例如:

public List<Card> getCards() { ... }

它返回卡片组中的卡片列表。 然后,在你insertionSort方法,而不是listToSort[k]你就必须listToSort.getCards().get(k) 此外,不是使用<您可以使用CardComparator的新实例来确定是否交换卡。

public static void insertionSort(DeckOfCards cardsToSort) {
    final Comparator cardComparator = new CardComparator();
    for (int i = 0; i < cardsToSort.size() - 1; i++) {
        for (int k = i + 1; k > 0; k--) {
            final Card card1 = cardsToSort.getCards().get(k);
            final Card card2 = cardsToSort.getCards().get(k - 1);
            if(cardComparator.compare(card1, card2) < 0) {
                swap(cardsToSort, k, k-1);
            } else {
                break;
            }
        }
    }
} 

listToSort是阵列DeckOfCards //Code breaks here所示的行上,您试图比较两个DeckOfCards对象,这些对象在java中是无法做到的(其他语言中的运算符重载将允许您执行此操作)。

你怎么写一个方法,比如.getSortValue()给你一个值来排序。 或者你可以写一些东西比较卡内的值,如:

if(listToSort[k].getSuit().getOrder()*13+listToSort[k].getFace().getOrder() < listToSort[k- 1].getSuit().getOrder()*13+listToSort[k-1].getFace().getOrder())

...这有点长,但我会假设做你想要的。

注意*13表示西装和面部的每个组合都是独一无二的

TLDR:如果您想以任何其他顺序对其进行排序,您必须从每张卡中提取一个值,以便您可以正确比较

正确的方法是将整个套牌拆分成套装,然后单独对每个套件进行分类。 您的插入排序版本无法正常工作,因为排序是使用面值进行的,即aces,2,3,4 ......我不会将其视为排序。

private HashMap<Suite,ArrayList<Cards>> deck ;

//scan through the whole deck

for(int i = 0;i < 52; ++i) {

    `switch(cards[i]) {`

      `case Aces :`
        deck.put(Suite.Aces,cards[i]) ;
        break;
    .....
}

}

//Now sort

sort(deck.get(Suite.Aces)) ;

sort(deck.get(Suite.Diamond)) ;

暂无
暂无

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

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