0

I need to double each letter in a string using a for loop and an if-then statement. How can you comb through a string and test if each character is a letter or a symbol like an exclamation point? And then print the string back out with each letter doubled and each exclamation point tripled.

This is what I have so far. It's unfinished and it doesn't work at all, but am I on the right track?

import java.util.Scanner;

public class DoubleLetters{
  public static void main(String[] args){
  Scanner scan = new Scanner(System.in);

  System.out.println("Enter a sentence:");
  String sentence = scan.nextLine();

  boolean isLetter = false;

  for (int i = 0; i < sentence.length(); i++){
    isLetter = Character.isLetter(sentence.charAt(i));
    if (i == sentence.length() || sentence.charAt(i) == ' ' || isLetter == false){
    System.out.print(sentence.charAt(i) + sentence.charAt(i));
  }
}
fabian
  • 80,457
  • 12
  • 86
  • 114
Typag4
  • 19
  • 1
  • 5
    I would consider using a `StringBuilder` – 3kings Mar 17 '16 at 16:28
  • Explain (in an edit to your question) what you imagine the condition `i == sentence.length() || sentence.charAt(i) == ' ' || isLetter == false` to do, and I will answer your question. – Mad Physicist Mar 17 '16 at 16:29
  • 2
    How do you expect `i == sentence.length()` to become `true`? Also `char+char` != `String` – fabian Mar 17 '16 at 16:29
  • I don't understand why the `StringBuilder` comment was upvoted that much. `StringBuilder` is an improvement over `String` concatenation, of which there is none there. – Aaron Mar 17 '16 at 16:40
  • What you need to do is comment what you're doing. If you can explain to someone in English what is happening to the parser at every single step, you can probably get it to work yourself. Here are two tips. 1) Using "words" instead of the whole line will help you think about it better. 2) Make sure you print something at each iteration (once or twice), which will help you debug. – ergonaut Mar 17 '16 at 16:40
  • I had the if statement layed out differently at first. I found whats there now on another question and was just experimenting with what it did. – Typag4 Mar 17 '16 at 17:10

3 Answers3

1

It looks like you were on the right way, then passed the right exit and carried on the wrong way.

for (int i = 0; i < sentence.length(); i++){ [...] } is a right way to iterate over a string's characters.

Character.isLetter(c) is a right way to check whether a character is a letter.

However, your condition is chaotic :

  • why would you make special conditions for spaces and end characters?
  • why is your isLetter condition negated?

I think your condition should simply be

if (isLetter) { /* print twice */ } 
else if (isExclamationPoint) { /* print "thrice" */ }
else { /* print once */ }
Idos
  • 15,053
  • 14
  • 60
  • 75
Aaron
  • 24,009
  • 2
  • 33
  • 57
0

Try this:

    import java.util.*;

    public class DoubleLetters{
      public static void main(String[] args){
          Scanner scan = new Scanner(System.in);

          System.out.println("Enter a sentence:");
          String sentence = scan.nextLine();

          StringBuilder sb = new StringBuilder();
          for (Character c: sentence.toCharArray()){
            sb.append(c);

            if(Character.isLetter(c)){
                sb.append(c);
            }
            else if(c == '!'){
                sb.append(c).append(c);
            }
          }
          sentence = sb.toString();
          System.out.println(sentence);
      }
    }
pczeus
  • 7,709
  • 4
  • 36
  • 51
  • Hey that works! Thanks so much. I'm not familiar at all with the stringBuilder class or arrays so I didn't try to use it but this does seem like the simplest way to do it. – Typag4 Mar 17 '16 at 17:08
  • Great. If the answer works for you, please mark it as the correct one and/or upvote it. – pczeus Mar 17 '16 at 17:09
0

When manipulating strings like this, it is best to use StringBuilder, which allocates a contiguous character buffer of a given size. You can count how big your output String needs to be, and pass this size to the StringBuffer on construction.

I would also recommend continuing to call String.charAt for maximum efficiency.

You may also want to encapsulate your routine in a function. You can take the input as a CharSequence for maximum utility.

public class DoubleLetters {
    private static int getRepetitionCount(char c) {
        if (Character.isLetter(c)) {
            return 2;
        } else if (c == '!') {
            return 3;
        } else {
            return 1;
        }
    }

    public static String doubleLetters(CharSequence in) {
        int inLength = in.length();
        int outLength = 0;

        for (int i = 0; i < inLength; ++i) {
            outLength += getRepetitionCount(in.charAt(i));
        }

        StringBuilder out = new StringBuilder(outLength);

        for (int i = 0; i < inLength; ++i) {
            char c = in.charAt(i);
            int reps = getRepetitionCount(c);

            for (int r = 0; r < reps; ++r) {
                out.append(c);
            }
        }

        return out.toString();
    }

    public static void main(String[] args) {
        String test = "hello! world!";
        System.out.print(doubleLetters(test));
    }
}

In this specific case, you could alternatively allocate a buffer of size 3 * inLength, which will be large enough to hold any potential output string.

Joseph Thomson
  • 9,888
  • 1
  • 34
  • 38