简体   繁体   中英

writing a method that takes an array of strings and orders the strings by number of vowels from least to greatest, and keeps the alphabetical order

The goal of this program is to change the array of strings given to make the array show the string with the least amount of vowels to the greatest while having it in alphabetical order. The output should look like this :

[hello, Apple, hat, cat, Banana, AAA]
[cat, hat, Apple, hello, AAA, Banana]

My code:

public static void main(String[] args) {
    String[] strings = {"hello", "apple", "hat", "cat", "Banana", "AAA"};
    System.out.println(Arrays.toString(strings));
    orderByVowels(strings);
}

public static void orderByVowels(String[] order) {
    for(int i = 0; i < order.length; i++) {
        for(int j = i+1; j < order.length; j++) {
            if(order[i].compareTo(order[j]) > 0) {
                String tppp = order[i];
                order[i] = order[j];
                order[j] = tppp;
            }
        }
    }
    for (String order1 : order) {
        System.out.print(order1 + " ");
    }
}

My problem is the output puts the order of the strings in the right order but its not in an array. How can I put the new string order into an array and print it out to be like the output I showed above?

We first need to write a method to calculate vowel count in a string. Once that is done, we need to use both vowel count and string comparison in sorting logic. Below example should work:

public static void main(String[] args) {
    String[] strings = { "hello", "apple", "hat", "cat", "Banana", "AAA" };
    // Displaying the initial array..
    System.out.println(Arrays.toString(strings));
    orderByVowels(strings);
    System.out.println(Arrays.toString(strings));
}

public static void orderByVowels(String[] order) {

    for (int i = 0; i < order.length; i++) {
        for (int j = i + 1; j < order.length; j++) {
            int countI = getVowelCount(order[i]);
            int countJ = getVowelCount(order[j]);
            if(countI > countJ
                    || (countI == countJ && order[i].compareTo(order[j]) > 0)){
                String tppp = order[i];
                order[i] = order[j];
                order[j] = tppp;
            }
        }
    }
}

public static int getVowelCount(String input){
    int count = 0;
    for (int j = 0; j < input.length(); j++) {
        char c =input.toLowerCase().charAt(j);
        if(c=='a')
            count++;
        else if(c=='e')
            count++;
        else if(c=='i')
            count++;
        else if(c=='o')
            count++;
        else if(c=='u')
            count++;
    }
    return count;
}

As of late, I've been a fan of Guava's Ordering class. If you're not adverse to using Lists and a library from Google, it has exactly what you're looking for with its Ordering.compound(secondaryComparator) method, which uses a secondaryComparator in the event of a tie in the first comparator.

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import com.google.common.collect.Ordering;
import com.google.common.primitives.Ints;

public class SortStringArray {

    public static void main(String[] args) {
        final String[] testArray = 
            {"hello", "Apple", "hat", "cat", "Banana", "AAA"};
        final List<String> testList = Arrays.asList(testArray);

        final Ordering<String> byNumVowels = new Ordering<String>() {
            @Override
            public int compare(String left, String right) {
                return Ints.compare(vowelCount(left), vowelCount(right));
            }

            private int vowelCount(final String str) {
                if (str == null) {
                    return 0;
                }

                int count = 0;
                final String strLowercase = str.toLowerCase();
                for (int i = 0; i < strLowercase.length(); i++) {
                    final char c = strLowercase.charAt(i);
                    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
                        count++;
                    }
                }
                return count;
            }
        };

        Collections.sort(testList, byNumVowels.compound(Ordering.natural()));
        System.out.print(testList);
    }
}

The magic happens here:

Collections.sort(testList, byNumVowels.compound(Ordering.natural()));

where the comparator you define is checked against first, and in the event of a tie, uses the natural ordering (lexicographical).

Note: The comparator returned by Ordering.natural() will throw a null pointer exception if it is given a null String. Ordering provides a easy readable way to handle this as well:

Collections.sort(testList, byNumVowels.nullsFirst().compound(Ordering.natural()));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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