2

I have written a comparator which is calculating consonants in a given string to compare 2 strings, but it is somehow making TreeSet think that 2 strings are equal (may be when they are of same size).

public class SortDiff {
public static void main(String[] s1) {

    List<String> list = Arrays.asList("century", "army", "spit", "twin", "frog", "guideline", "impulse",
            "distributor", "hallway", "appeal", "fitness", "pudding", "mild", "enter", "kitchen", "constitutional",
            "die", "condition", "morsel", "jealous", "colorful", "myth", "belly", "rugby", "valid", "shot",
            "locate", "preference", "representative", "chart", "prince", "think", "threshold", "health", "sweater",
            "volume", "poison", "lease", "toast", "diplomat", "trait", "cower", "slime", "handy", "example",
            "sanctuary", "board", "crash", "large", "attract", "censorship", "room", "license", "smoke", "roll",
            "taste", "inflate", "continuation", "establish", "fault", "gown", "dirty", "width", "qualify",
            "reference", "excitement", "vegetable", "wear", "confusion", "concept", "willpower", "snarl", "develop",
            "integration", "pie", "respectable", "fast", "limit", "shaft", "acceptance", "insert", "brown", "death",
            "effective", "ticket", "play", "highway", "lot", "tablet", "mother", "pier", "facility", "match",
            "animal", "sport", "laundry", "negligence", "white", "vat", "nuclear");
    System.out.println(list.size() + "=====");
    TreeSet<String> tree = new TreeSet<String>(new sortByConsonants());//
    int count = 0;
    for (String s : list) {
        count++;
        System.out.println(s);
        System.out.println(tree.add(s));
    }
    System.out.println("===>" + count);
    System.out.println(tree.size() + "=====");
    Iterator itr = tree.iterator();
    while (itr.hasNext()) {
        System.out.println(itr.next());
    }
}


}

This is the comparator class which I am passing to TreeSet.

class sortByConsonants implements Comparator<String>{

    public int compare(String a, String b) 
    { 

        return count(a,2)-count(b,2);
    } 
    public boolean equals(String a,String b) {

        return a.equals(b);

    }

    public int count(String line,int type) {
        int vowels = 0, consonants = 0, digits = 0, spaces = 0;

        line = line.toLowerCase();
        for(int i = 0; i < line.length(); ++i)
        {
            char ch = line.charAt(i);
            if(ch == 'a' || ch == 'e' || ch == 'i'
                || ch == 'o' || ch == 'u') {
                ++vowels;
            }
            else if((ch >= 'a'&& ch <= 'z')) {
                ++consonants;
            }
            else if( ch >= '0' && ch <= '9')
            {
                ++digits;
            }
            else if (ch ==' ')
            {
                ++spaces;
            }
        }

        if(type==1) {
            return vowels;
        }else {
            return consonants;
        }

    }

}

Can someone please look into it and find what mistake I am making!!

Goal : I want to sort strings based on count of consonants (Without use of library sort() method)

Edit : changed to comparator logic to

public int compare(String a, String b) 
    { 
        if(count(a,2)-count(b,2)==0) {
            return 1;
        }
        return count(a,2)-count(b,2);
    } 

Still not working!!

Edit = For this question TreeSet is not the right Data Structure, should use ArrayList.

Rishi
  • 1,646
  • 2
  • 15
  • 34

2 Answers2

2

Change your SortByConsonants to the following. (Note that class names should start with a capital letter)

class SortByConsonants implements Comparator<String> {

    public int compare(String a, String b) {
        if (count(a) - count(b) == 0) {
            return 1;
        }
        return count(a) - count(b);
    }

    public boolean equals(String a, String b) {
        return a.equals(b);
    }

    public int count(String line) {
        int consonants = 0;
        line = line.toLowerCase();
        for (int i = 0; i < line.length(); ++i) {
            char ch = line.charAt(i);
            if (ch != 'a' && ch != 'e' && ch != 'i' && ch != 'o' && ch != 'u') {
                consonants++;
            }
        }
        return consonants;
    }

}

Also, since we are just interested to sort based on the count of consonants there is no need to calculate the number of vowels, spaces, digits, etc. Furthermore, there is also no need of passing in another parameter type to the method count

Nicholas K
  • 15,148
  • 7
  • 31
  • 57
  • 1
    well, you actually fixed my broken count method, Kudos. Now the problem remains is that I need to sort the String Objects based on number of consonants. Could you please help me with that also? – Rishi Jan 31 '19 at 17:33
  • I did , its returning 11 elements only ( all of different size);===>100 11===== die army enter appeal century colorful guideline preference distributor continuation constitutional – Rishi Jan 31 '19 at 17:35
  • Ah I see. Why even use a *TreeSet*? You could simply sort the list using : `list.sort(new sortByConsonants());` And now print it `list.forEach(System.out::println);` – Nicholas K Jan 31 '19 at 17:39
  • I want to sort the strings without using sort method; Thats why I used this particular logic. – Rishi Jan 31 '19 at 17:41
  • 1
    I have edited the answer. The reason they were getting omitted is because when the number of consonants are equal we aren't doing anything. Also there is no need to count the number of vowels, spaces, etc. – Nicholas K Jan 31 '19 at 18:03
1

Your comperator as you coded it, will return 0 (meaning equality)
if 2 strings have the same number of consonants.
You defined:

TreeSet<String> tree = new TreeSet<String>(new sortByConsonants());

so in tree there can't exist 2 items (strings) with the same number of consonants

forpas
  • 160,666
  • 10
  • 38
  • 76
  • Okays, seems my logic is flawed. Can you please help me achieve my goal (edited the question) – Rishi Jan 31 '19 at 17:34
  • I understand that you want the items sorted by the number of consonants. But why use a Treeset? This restricts the items you store in it. – forpas Jan 31 '19 at 17:42
  • I thought Tree would keep the strings sorted based on the custom comparator logic I would provide in the constructor but it's not working the way it suppose to work. Can you please suggest something on it? – Rishi Jan 31 '19 at 17:45
  • An arraylist can use a custom comperator to sort the items. – forpas Jan 31 '19 at 17:46
  • Then I would be needed to call sort method of arrayList; requirement is to not use that. – Rishi Jan 31 '19 at 17:47