-1

I am writing a program that takes an input. This input gets placed in different arrays. Each array is of 'char' data type. I need to have each array organized from greatest to least in value. Each array represents a suit in playing cards; hearts, spades etc. The values that need to be organized are the values of these cards. The order hierarchy is as follows. A to K to Q to J to T (representing '10'), then 9 to 8 to 7 to 6 to 5 to 4 to 3 to 2. The problem I have is implementing the quick sort algorithm to work with letters and numbers alike. Here are my methods.

public static void quickSort (int a[], int start, int end)
{
if (start < end)
{ 
  int split = partition (a, start, end);

   // show split
  System.out.println ("split " + split);
  System.out.println ("");

   // sort the left sublist
  quickSort (a, start, split);

   // now sort the right sublist
  quickSort (a, split + 1, end);
  }
}

public static int partition (int a[], int start, int end)
{ 
int bottom = start - 1;
int top = end + 1;

 // pick a value pivot.Arrange the list according to: <= or >= to pivot

int pivot = a [start];

System.out.println ("pivot is " + pivot);

 // walk bottom and top towards each other, using them to swap array
 // elements as we go, and stopping when bottom and top pass each other

while (bottom < top)
{
   // walk until you find an element that is not in its current sublist

  do
  {
    bottom++;
  }
  while (a [bottom] < pivot);

  do
  {
    top--;
  }
  while (a [top] > pivot);

   // swap a[bottom] and a[top], thus putting the values in the
   // correct sublist

  int temp = a [bottom];
  a [bottom] = a [top];
  a [top] = temp;
}

 // undo the last swap that took place after the bottom and top
 // indices passed each other

int temp = a [bottom];
a [bottom] = a [top];
a [top] = temp;

 // finally, return split index
return top;

}
}

Input: 4C3C6CTSTHAD2S8DACQHKS2D4H Expected Output: Spades K 10 2 Hearts Q 10 4 Diamonds A 8 2 Clubs A 6 4 3

The output that I get is out of order. I call the method once for each suit.

  • Where is the problem? What is the output you are getting, and what is the expected output? https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems – Higigig May 09 '20 at 19:52
  • I edited the post to include those things you mentioned. At the bottom of the post – Luca Galati May 09 '20 at 20:08

1 Answers1

1

I have followed these steps to sort the card of each suit in reverse order

Step1: Read the input string and split by length of 2 because each card in the input is represented by 2 Characters. For example, the input string '6CTS' means the card is 6 of Club and Ten of Spades.

Step2: Modify the input from String representation to numeric representation. We wanted to use the quicksort function that you have implemented. Your quicksort needs the input array to be of integer type so I manipulated the input string to be in that format. For example, TS will become 10 of the Spades. JH will become 11 of Heart and so on.

Step3: Use your quicksort method to sort each of the suits by iterating over them.

The implementation of the above approach is in the snippet below.

import com.google.common.primitives.Ints;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Main {

    public static void quickSort(int a[], int start, int end) {
        if (start < end) {
            int split = partition(a, start, end);

            // show split
//            System.out.println("split " + split);

            // sort the left sublist
            quickSort(a, start, split);

            // now sort the right sublist
            quickSort(a, split + 1, end);
        }
    }

    public static int partition(int a[], int start, int end) {
        int bottom = start - 1;
        int top = end + 1;

        // pick a value pivot.Arrange the list according to: <= or >= to pivot

        int pivot = a[start];

//        System.out.println("pivot is " + pivot);

        // walk bottom and top towards each other, using them to swap array
        // elements as we go, and stopping when bottom and top pass each other

        while (bottom < top) {
            // walk until you find an element that is not in its current sublist

            do {
                bottom++;
            }
            while (a[bottom] < pivot);

            do {
                top--;
            }
            while (a[top] > pivot);

            // swap a[bottom] and a[top], thus putting the values in the
            // correct sublist

            int temp = a[bottom];
            a[bottom] = a[top];
            a[top] = temp;
        }

        // undo the last swap that took place after the bottom and top
        // indices passed each other

        int temp = a[bottom];
        a[bottom] = a[top];
        a[top] = temp;

        // finally, return split index
        return top;

    }

    public static void main(String[] args) {
        Map<String, Integer> cardValueMap = new HashMap<>();
        // append the value as per the priority of the card
        cardValueMap.put("T", 10);
        cardValueMap.put("J", 11);
        cardValueMap.put("Q", 12);
        cardValueMap.put("K", 13);
        cardValueMap.put("A", 14);
        String inputString = "4C3C6CTSTHAD2S8DACQHKS2D4H";
        readInput(inputString, cardValueMap);
    }

    static void readInput(String inputString, Map<String, Integer> cardValueMap) {
        String[] cardInput = splitToNChar(inputString, 2); // each input is of size 2 as per the problem
        Map<String, List<Integer>> allCardMap = new HashMap<>();
        for (String eachCard : cardInput) {
            String[] tempCardToProcess = splitToNChar(eachCard, 1);
            List<Integer> existingList = allCardMap.get(tempCardToProcess[1]);
            if (existingList == null) {
                existingList = new ArrayList<>();
            }

            existingList.add(getNumericValueOfCard(tempCardToProcess[0], cardValueMap));
            allCardMap.put(tempCardToProcess[1], existingList);
        }

        System.out.println("allCardMap before sorting is = " + allCardMap);

        for (Map.Entry<String, List<Integer>> entry : allCardMap.entrySet()) {
            String suitType = entry.getKey();
            List<Integer> presentCardList = entry.getValue();
            List<Integer> sortedPresentCardList = getSortedUsingQuickSort(presentCardList);
            Collections.reverse(sortedPresentCardList); // needed in reverse order
            allCardMap.put(suitType, sortedPresentCardList);
        }
        System.out.println("allCardMap after sorting is = " + allCardMap);
        // Do the post processing of the output as per your requirement.
        // For example if you want to see D as diamond, S as spade. Print accordingly.
    }

    /**
     * Split text into n number of characters.
     *
     * @param text the text to be split.
     * @param size the split size.
     * @return an array of the split text.
     */
    private static String[] splitToNChar(String text, int size) {
        List<String> parts = new ArrayList<>();

        int length = text.length();
        for (int i = 0; i < length; i += size) {
            parts.add(text.substring(i, Math.min(length, i + size)));
        }
        return parts.toArray(new String[0]);
    }

    static Integer getNumericValueOfCard(String cardString, Map<String, Integer> cardValueMap) {
        boolean isNumeric = cardString.chars().allMatch(Character::isDigit);
        Integer valueToInsert;
        if (!isNumeric) {
            valueToInsert = cardValueMap.get(cardString);
        } else {
            valueToInsert = Integer.valueOf(cardString);
        }
        return valueToInsert;
    }

    static List<Integer> getSortedUsingQuickSort(List<Integer> cardList) {
        int[] suitArray = Ints.toArray(cardList);
        quickSort(suitArray, 0, suitArray.length - 1);
        return Arrays.stream(suitArray)        // IntStream
                .boxed()        // Stream<Integer>
                .collect(Collectors.toList());
    }

}

Let me know if you feel any difficulty in understanding the above code.

Ajay Kr Choudhary
  • 1,304
  • 1
  • 14
  • 23