fpm21
fpm21

Reputation: 13

StringUtils problems. How to fix this String alphabet letter check?

This code takes an input string from the user, which may contain special characters. We then output the letters that are missing from the alphabet. For example, "the quick brown fox jumped over the lazy dog" would have an empty string returned, but "ZYXW, vu TSR Ponm lkj ihgfd CBA." would be missing the letters "eq".

Currently, my program is returning the whole alphabet instead of only the missing characters.


import java.io.*;

import org.apache.commons.lang3.*;

public class QuickBrownFox {

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String s = reader.readLine();
        s = s.toUpperCase();
        String[] arr = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
                "T", "U", "V", "W", "X", "Y", "Z" };
        String chars_only = "";
        for (int i = 0; i < s.length(); i++) {
            for (int j = 0; j < arr.length; j++) {
                if (s.substring(i, i + 1).equals(arr[j])) {
                    chars_only += s.substring(i, i + 1);
                }
            }
        }
        System.out.println(chars_only); // now we have a string of only alphabet letters
        String missing = "";
        for (int j = 0; j < arr.length; j++) {
            if (StringUtils.contains(arr[j], chars_only) == false) { // alphabet letter not found
                missing += arr[j];
            }
        }
        missing = missing.toLowerCase();
        System.out.println("missing letters: " + missing);
    }
}

Upvotes: 0

Views: 224

Answers (2)

Traian GEICU
Traian GEICU

Reputation: 1786

One option is to use a Set initialized with given alphabet-chars. Then remove from set any chars contained in input-string. Remainder will reflect missing chars.

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class TestAlphabet {
    public static void main(String[] args) {
        
        Set<Character> set = new HashSet<Character>();
        Character[] arr = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
                'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
        Collections.addAll(set, arr);
        String s1="abc";
        System.out.println("input:"+s1);
        new TestAlphabet().new Missing().getMissing(set, s1).forEach(System.out::print);
        System.out.println("\n");
        String s2="the quick brown fox jumped over the lazy dog";
        System.out.println("input:"+s2);
        new TestAlphabet().new Missing().getMissing(set, s2).forEach(System.out::print);
        System.out.println("\n");
        String s3="ZYXW, vu TSR Ponm lkj ihgfd CBA.";
        System.out.println("input:"+s3);
        new TestAlphabet().new Missing().getMissing(set, s3).forEach(System.out::print);
    }
    class Missing
    {
        public Set<Character> getMissing(Set<Character> orig, String s)
        {
            //keep origin
            Set<Character> set = new HashSet<Character>();
            set.addAll(orig);
            s=s.toUpperCase();
            for(int i=0;i<s.length();i++)
            {
                Character c=s.charAt(i);
                set.remove(c);
            }
            return set;
        }
    }
}

Output

input:abc
DEFGHIJKLMNOPQRSTUVWXYZ

input:the quick brown fox jumped over the lazy dog
S

input:ZYXW, vu TSR Ponm lkj ihgfd CBA.
EQ

Upvotes: 0

Helios
Helios

Reputation: 195

StringUtils.contains(arr[j], chars_only) checks whether the alphabet letter (arr[j]) contains the whole string chars_only which will never be the case (unless you enter just one character). What you want is !chars_only.contains(arr[j]) (no need to use StringUtils.contains). This will check whether the inputted letters do not contain the jth alphabet letter. Alternatively you can keep StringUtils.contains, just swap the parameters: !StringUtils.contains(chars_only, arr[j]).

Btw, you could use streams to reduce the amount of code:

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

import java.io.*;
import java.util.stream.Collectors;

public class QuickBrownFox {
  public static void main(String[] args) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = reader.readLine().toUpperCase();

    List<String> alphabet = Arrays.asList("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
      "T", "U", "V", "W", "X", "Y", "Z");
    String missing = alphabet.stream()
      .filter(letter -> !s.contains(letter))
      .collect(Collectors.joining())
      .toLowerCase();

    System.out.println("missing letters: " + missing);
  }
}

Upvotes: 0

Related Questions