Stuck on how to "append a period" into an acronym

1k Views Asked by At

An acronym is a word formed from the initial letters of words in a set phrase. Define a method named createAcronym that takes a string parameter and returns the acronym of the string parameter. Append a period (.) after each letter in the acronym. If a word begins with a lower case letter, don't include that letter in the acronym. Then write a main program that reads a phrase from input, calls createAcronym() with the input phrase as argument, and outputs the returned acronym. Assume the input has at least one upper case letter.

Ex: If the input is:

Institute of Electrical and Electronics Engineers

the output should be:

I.E.E.E.

Ex: If the input is:

Association for computing MACHINERY

the output should be:

A.M.

The letters ACHINERY in MACHINERY don't start a word, so those letters are omitted.

The program must define and call a method:

public static String createAcronym(String userPhrase)

So far my code looks like this:

import java.util.Scanner;

public class LabProgram {
   
     public static String createAcronym(String userPhrase) {

       String[] separatedWords = userPhrase.split(" ");

       String acronymAlphabets = " ";

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

           if(Character.isUpperCase(separatedWords [i].charAt(0))) {

               acronymAlphabets += Character.toUpperCase(separatedWords [i].charAt(0));

           }

       }

       return acronymAlphabets;

   }
   
   public static void main(String[] args) {
       Scanner userInput = new Scanner(System.in);

       System.out.println(createAcronym(userInput.nextLine()));
   }
}

The system returns the correct acronym but cant for the life of me figure out how to get the periods in the proper place. Side note: Im really good at getting them at the beginning or end of them. Any help "appending" this problem would be awesome!

4

There are 4 best solutions below

0
WJS On BEST ANSWER

Change
acronymAlphabets += Character.toUpperCase(separatedWords [i].charAt(0));
to
acronymAlphabets += Character.toUpperCase(separatedWords [i].charAt(0))+".";

Here is one way using streams.

String[] titles = {"Institute of Electrical and Electronics Engineers",     
    "Association for Computing MACHINERY",
    "Association of  Lions, and Tigers, and Bears, oh my!!"};

for (String title : titles) {
    System.out.println(createAcronym(title));
}

prints

I.E.E.E
A.C.M
A.L.T.B
  • Split on anything that isn't a word and stream the array
  • filter any words not starting with an upper case character.
  • Map the first letter of each word to a String.
  • and join together with a period between each word.
public static String createAcronym(String title) {
    return Arrays.stream(title.split("\\W+"))
            .filter(str -> Character.isUpperCase(str.charAt(0)))
            .map(str -> str.substring(0, 1))
            .collect(Collectors.joining("."));
}
0
Persixty On

Don't you just need to append a period (.) after each letter.

Add the following line at the end of the loop.

acronymAlphabets += ".";

Footnote: I would say the Answer offered by Kaan above using StringBuilder is better. I have offered an Answer making minimal chances to the code in the question. Given the OP is a novice I believe it's unhelpful to introduce too many new ideas in a reply. In programming and Java there's usually a dozen ways to do anything. Bombarding novices with new concepts only confuses them. One step at a time if you ask me.

0
Basil Bourque On

Other Answers, such as the one by WJS, give a direct, correct solution to the specifics of the Question: appending . to each capital letter. My Answer here is more for fun.

tl;dr

Using code points rather than char.

System.out.println(
        String.join(   // Join a bunch of strings into a single `String` object.
                "" ,   // Join the strings without any delimiter between them.
                Arrays.stream(  // Turn an array into a stream of elements for processing.
                                "Association of  Lions, and Tigers, and Bears, oh my!!"
                                        .split( " " )  // Returns an array of string objects, `String[]`. 
                        )
                        .filter( ( String part ) -> ! part.isBlank() )  // Skip any string elements without significant text.
                        .map( ( String part ) -> part.codePoints().boxed().toList() )  // Generate a stream of `int` integer numbers representing the code point numbers of each character in the string element. Via boxing, convert those `int` primitives into `Integer` objects. Collect the `Integer` objects into a `List`. 
                        .filter( ( List < Integer > codePoints ) -> Character.isUpperCase( codePoints.get( 0 ) ) )  // Skip any list of code points if the first code point represents a character other than an uppercase letter. 
                        .map( ( List < Integer > codePoints ) -> Character.toString( codePoints.get( 0 ) ) + "." )  // Extract the first code point `Integer` number, turn into a `String` containing the single character represented by that code point, and append a FULL STOP. 
                        .toList()  // Collect all those generated strings (single character plus FULL STOP) to a list.
        )
);

A.L.T.B.

Code points

I recommend making a habit of using code point integer numbers rather than the legacy char type. As a 16-bit value, char is physically incapable of representing most characters.

This code makes heavy use of streams. If not yet comfortable with streams, you could replace with conventional loops.

Pull apart the phrase.

    System.out.println( "input = " + input );
    String[] parts = input.split( " " );
    if ( parts.length == 0 ) { throw new IllegalArgumentException( "Input must consist of multiple words separated by spaces." ); }
    System.out.println( "parts = " + Arrays.toString( parts ) );

Convert each part of the phrase into code point integer numbers.

    List < List < Integer > > codePointsOfEachPart =
            Arrays
                    .stream( parts )
                    .filter( part -> ! part.isBlank() )
                    .map( part -> part.codePoints().boxed().toList() )
                    .toList();

Filter for those parts of the phrase that begin with an uppercase letter. From each of the qualifying parts, extract the first letter, append a FULL STOP, and collect to a list.

    List < String > abbreviations =
            codePointsOfEachPart
                    .stream()
                    .filter( ( List < Integer > codePoints ) -> Character.isUpperCase( codePoints.get( 0 ) ) )
                    .map( codePoints -> Character.toString( codePoints.get( 0 ) ) + "." )
                    .toList();

    // Join the collection of UppercaseLetter + FULL STOP combos into a single piece of text.
    String result = String.join( "" , abbreviations );

    return result;
}

When run:

input = Association of  Lions, and Tigers, and Bears, oh my!!
parts = [Association, of, , Lions,, and, Tigers,, and, Bears,, oh, my!!]
output = A.L.T.B.

Pull that all together for your copy-paste convenience.

private String acronym ( final String input )
{
    // Pull apart the phrase.
    System.out.println( "input = " + input );
    String[] parts = input.split( " " );
    if ( parts.length == 0 ) { throw new IllegalArgumentException( "Input must consist of multiple words separated by spaces." ); }
    System.out.println( "parts = " + Arrays.toString( parts ) );

    // Convert each part of the phrase into code point integer numbers.
    List < List < Integer > > codePointsOfEachPart =
            Arrays
                    .stream( parts )
                    .filter( part -> ! part.isBlank() )
                    .map( part -> part.codePoints().boxed().toList() )
                    .toList();

    // Filter for those parts of the phrase that begin with an uppercase letter.
    // From each of the qualifying parts, extract the first letter, append a FULL STOP, and collect to a list.
    List < String > abbreviations =
            codePointsOfEachPart
                    .stream()
                    .filter( ( List < Integer > codePoints ) -> Character.isUpperCase( codePoints.get( 0 ) ) )
                    .map( codePoints -> Character.toString( codePoints.get( 0 ) ) + "." )
                    .toList();

    // Join the collection of UppercaseLetter + FULL STOP combos into a single piece of text.
    String result = String.join( "" , abbreviations );

    return result;
}

That code could be shortened, into a single line of code! Not that I necessarily recommend doing so.

System.out.println(
        String.join(
                "" ,
                Arrays.stream(
                                "Association of  Lions, and Tigers, and Bears, oh my!!"
                                        .split( " " )
                        )
                        .filter( part -> ! part.isBlank() )
                        .map( part -> part.codePoints().boxed().toList() )
                        .filter( ( List < Integer > codePoints ) -> Character.isUpperCase( codePoints.get( 0 ) ) )
                        .map( codePoints -> Character.toString( codePoints.get( 0 ) ) + "." )
                        .toList()
        )
);

A.L.T.B.

0
Kaan On

Here's a solution that will include a starting letter if it is capitalized, and tack on a period (".") after any included letters.

A few comments:

  • Line 3: a StringBuilder is an efficient, powerful way to make small additions to a String
  • Line 5: use a "for" loop over the words (from line 2)
  • Line 6: isolate the starting character of "word"
  • Line 8: if firstChar is upper case, go ahead and append it to the StringBuilder result (no need to uppercase it again – it is already upper case or we wouldn't have made to line 8); and any time we append a letter, always go ahead and append a ".", too
  • Line 12: once we're done with all of the words, conver the StringBuilder to a String, and return the result
1.  public static String createAcronym(String input) {
2.     String[] words = input.split(" ");
3.     StringBuilder result = new StringBuilder();
4.
5.     for (String word : words) {
6.         char firstChar = word.charAt(0);
7.         if (Character.isUpperCase(firstChar)) {
8.              result.append(firstChar).append(".");
9.         }
10.    }
11.
12.    return result.toString();
13. }

You could further improve this by editing Line 2: instead of calling split() with a single space (" "), you could instead use a regular expressions to split on any number of whitespaces, tabs, etc.