2

I am tasked with taking a user sentence then separating it at the upper case letters as well as making those letters lower case after adding a " ".
I want to add a space add that position so that if user inputs "HappyDaysToCome" will output "Happy days to come".

Current code

  public static void main(String[] args)
  {
    Scanner s = new Scanner(System.in);
    System.out.println("Please enter a sentence");
    String sentenceString = s.nextLine();
    char[] sentenceArray = sentenceString.toCharArray();
    for(int i = 0; i < sentenceArray.length; i++)
    {
        if(i!=0 && Character.isUpperCase(sentenceArray[i]))
        {
            Character.toLowerCase(sentenceArray[i]); 
            sentenceArray.add(i, ' ');    
        }

    }
    System.out.println(sentenceArray)
    s.close();
  }
}
Community
  • 1
  • 1
David3734
  • 21
  • 1
  • 2
  • You can't insert things into arrays since they are fixed length. You should use a `StringBuilder`. – Andy Turner Sep 25 '16 at 17:49
  • This would be much simpler with regular expressions. See [this post](http://stackoverflow.com/questions/632204/java-string-replace-using-regular-expressions). – Nolo Sep 25 '16 at 23:16

3 Answers3

1

There is no add method for arrays. Arrays are not resizeable. If you indeed want to use a char[] array, you need to allocate one that is large enough, e.g. by counting the uppercase letters or simply by allocating a array that is surely large enough (twice the String length minus 1).

String input = ...

String outputString;

if (input.isEmpty()) {
    outputString = "";
} else {
    char[] output = new char[input.length() * 2 - 1];
    output[0] = input.charAt(0);
    int outputIndex = 1;
    for (int i = 1; i < input.length(); i++, outputIndex++) {
        char c = input.charAt(i);
        if (Character.isUpperCase(c)) {
            output[outputIndex++] = ' ';
            output[outputIndex] = Character.toLowerCase(c);
        } else {
            output[outputIndex] = c;
        }
    }
    outputString = new String(output, 0, outputIndex);
}

System.out.println(outputString);

Or better still use a StringBuilder

String input = ...

String outputString;

if (input.isEmpty()) {
    outputString = "";
} else {
    StringBuilder sb = new StringBuilder().append(input.charAt(0));

    for (int i = 1; i < input.length(); i++) {
        char c = input.charAt(i);
        if (Character.isUpperCase(c)) {
            sb.append(' ').append(Character.toLowerCase(c));
        } else {
            sb.append(c);
        }
    }
    outputString = sb.toString();
}

System.out.println(outputString);
fabian
  • 80,457
  • 12
  • 86
  • 114
0

You're approaching this the wrong way. Just add each char back to a new string but with spaces included at the right spots. Don't worry about modifying your char array at all. Here is a slight modification of your code:

  public static void main(String[] args)
  {
    Scanner s = new Scanner(System.in);
    System.out.println("Please enter a sentence");
    String sentenceString = s.nextLine();
    char[] sentenceArray = sentenceString.toCharArray();

    //new string to hold the output
    //starts with only the first char of the old string
    string spacedString = sentenceArray[0] + "";

    for(int i = 1; i < sentenceArray.length; i++)
    {
      if(Character.isUpperCase(sentenceArray[i]))
      {
        //if we find an upper case char, add a space and the lower case of that char
        spacedString = spacedString + " " + Character.toLowerCase(sentenceArray[i]);    
      }else {
        //otherwise just add the char itself
        spacedString = spacedString + sentenceArray[i];
      }
    }

    System.out.println(spacedString)
    s.close();
  }

If you want to optimize performance, you can use a StringBuilder object. However, for spacing out a single sentence, performance isn't going to make any real difference at all. If performance does matter to you, read more on StringBuilder here: https://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html

nhouser9
  • 6,730
  • 3
  • 21
  • 42
  • You know this is really inefficient, right? Don't concatenate strings in a loop, use a `StringBuilder`. – Andy Turner Sep 25 '16 at 17:51
  • @AndyTurner Seems to me like the author has a simple assignment and is looking for the simplest way to solve it. This isn't a question about efficiency; we are dealing with a single sentence. Efficiency is pretty much irrelevant for this use case. – nhouser9 Sep 25 '16 at 17:53
  • 1
    that OP doesn't ask for an efficient solution doesn't mean that you should give them an inefficient one. Use a `StringBuilder` to accumulate the String; it hardly changes the structure. – Andy Turner Sep 25 '16 at 17:58
  • @AndyTurner I repeat - for what the OP is asking for, performance is irrelevant. – nhouser9 Sep 25 '16 at 18:10
  • There's nothing wrong with creating examples that are "best practices". Especially if you want up-votes for an otherwise acceptable answer. No need to be obstinate; it was a legitimate suggestion. – michael Sep 27 '16 at 12:26
0

We basically want to tokenize the input string on uppercase letters. This can be done using the regular expression [A-Z][^A-Z]* (i.e., one uppercase, followed by zero or more "not" uppercase). The String class has a built-in split() method that takes a regular expression. Unfortunately, you also want to keep the delimiter (which is the uppercase letter), so that slightly complicates matters, but it can still be done using Pattern and Matcher to put the matched delimiter back into the string:

import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.List;
import java.util.ArrayList;
public class Foo {
  public static void main(String[] args) {
    String text = "ThisIsATest1234ABC";
    String regex = "\\p{javaUpperCase}[^\\p{javaUpperCase}]*";
    Matcher matcher = Pattern.compile(regex).matcher(text);
    StringBuffer buf = new StringBuffer();
    List<String> result = new ArrayList<String>();
    while(matcher.find()){
        matcher.appendReplacement(buf, matcher.group());
        result.add(buf.toString());
        buf.setLength(0);
    }   

    matcher.appendTail(buf);
    result.add(buf.toString());
    String resultString = ""; 
    for(String s: result) { resultString += s + " "; }
    System.out.println("Final: \"" + resultString.trim() + "\"");
  }
}

Output:

Final: "This Is A Test1234 A B C"
michael
  • 9,161
  • 2
  • 52
  • 49