简体   繁体   中英

Extracting and printing each letter from a String only once

I'm currently writing an algorithm that takes a user's input, identifies each letter in the entire string, and then prints each letter out along with printing out the number of how many times it appears in that string right next to it. Currently, the algorithm traverses the string and performs the desired actions, but does not group the letters together as shown in the example at the bottom.

I am stuck on what I could do to fix this and would appreciate advice. I am intermediate with Java and chose not to mess with Arrays in this context.

PS It is designed to exclude spaces.

//Algorithm
    String newS2 = "";
    String storage = "";
    int repeated = 0;
    
    for(int i = 0; i<userS.length(); i++){
      if(!userS.substring(i, i + 1).equals(" ") && !(userS.substring(i, i + 1).equals(storage.substring(0)))){
        for(int j = 0; j<userS.length(); j++){
          if(userS.substring(j, j + 1).equals(userS.substring(i, i + 1))){
            storage += userS.charAt(j);
          }
        }
        repeated = storage.length();
        newS2 += storage.charAt(0) + String.valueOf(repeated);
        repeated = 0;
        storage = "";
      }
    }

userS is a previously initialized String variable that is set to what the user inputs via a Scanner variable.

Currently, if I input "This message", I get: t1h1i1s3m1e2s3s3a1g1e2 when I really want to get: t1h1i1s3m1e2g1

Would using some data structures be an option?

In Java you can use a type like LinkedHashMap that preserves the order of entries.

Try this:

        Map<Character, Integer> stringCounts = new LinkedHashMap<>();

        String userS = "This message";

        for(int i = 0; i<userS.length(); i++){

            char c = userS.charAt(i);
            if(Character.isWhitespace(c)) {   // Ignore Whitespace
                continue;
            }

            stringCounts.putIfAbsent(c, 0);  // Add counter for this character if not there already
            stringCounts.put(c, (stringCounts.get(c) + 1));

        }

        StringBuilder bld = new StringBuilder();
        for( Map.Entry<Character, Integer> e : stringCounts.entrySet()) {
            bld.append(e.getKey()).append(e.getValue());
        }


        // Printout to check solution
        System.out.println(bld.toString());

This produces output:

T1h1i1s3m1e2a1g1

You're not keeping track of letters that have already appeared in your source string, so all the extra stuff in your new String are the additional occurrences of each character with the total number of times that character appears over the remainder of the string.

You need an additional check to see whether you've already encountered a letter. Try using String.contains() to exclude duplicate characters. The logic is: if the new string doesn't already contain this character, I should add the character. Otherwise, do nothing.

if(!newS.contains(storage.substring(0, 1))
{
    storagestorage += userS.charAt(j);
}

You really should be using some sort of data structure, however. Java has data structures for a reason. Try using a HashMap where the single character String is the key and the number of repetitions is the value and you'll have a compact piece of code that's dead easy to follow. Right now, your approach is a bit unintuitive because you're building up storage character by character and deriving the repetitions based on how many times that character is stored instead of simply incrementing a counter.

HashMap<String, Integer> myMap = new HashMap<>();

for(int count = 0; count < userS.length(); count++)
{
    String sub = userS.subString(count, count + 1);

    if(myMap.containsKey(sub))
    {
        // this char is already in the map
        myMap.replace(sub, new Integer(myMap.get(sub) + 1));
    }
    else
    {
        myMap.put(sub, new Integer(1));
    }
}

I think that's right, pardon typos as I'm on mobile at the moment.

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