Java Programming: Replace all but first and last letters of each word with “_”How do I efficiently iterate over each entry in a Java Map?How does the Java 'for each' loop work?Including all the jars in a directory within the Java classpathHow to capitalize the first character of each word in a stringView if a word's letters are in ascending orderDoubling each letter in a StringHow to have an input of letters and change them to uppercase and lower case? JAVASomething going wrong with the charAt method?checking if first char is equal to last charMy do while loop isn't working?
Is "remove commented out code" correct English?
A category-like structure without composition?
Reverse dictionary where values are lists
How do I gain back my faith in my PhD degree?
How seriously should I take size and weight limits of hand luggage?
Solving a recurrence relation (poker chips)
Why didn't Miles's spider sense work before?
How can saying a song's name be a copyright violation?
Forgetting the musical notes while performing in concert
Can I run a new neutral wire to repair a broken circuit?
What is a romance in Latin?
Cursor Replacement for Newbies
What reasons are there for a Capitalist to oppose a 100% inheritance tax?
How badly should I try to prevent a user from XSSing themselves?
Would Slavery Reparations be considered Bills of Attainder and hence Illegal?
ssTTsSTtRrriinInnnnNNNIiinngg
What method can I use to design a dungeon difficult enough that the PCs can't make it through without killing them?
Why is it a bad idea to hire a hitman to eliminate most corrupt politicians?
CAST throwing error when run in stored procedure but not when run as raw query
Why would the Red Woman birth a shadow if she worshipped the Lord of the Light?
Why can't we play rap on piano?
Avoiding the "not like other girls" trope?
Assassin's bullet with mercury
Why no variance term in Bayesian logistic regression?
Java Programming: Replace all but first and last letters of each word with “_”
How do I efficiently iterate over each entry in a Java Map?How does the Java 'for each' loop work?Including all the jars in a directory within the Java classpathHow to capitalize the first character of each word in a stringView if a word's letters are in ascending orderDoubling each letter in a StringHow to have an input of letters and change them to uppercase and lower case? JAVASomething going wrong with the charAt method?checking if first char is equal to last charMy do while loop isn't working?
The purpose of this method is replace all but the first and last letters of each word with "_". I'm a complete novice when it comes to coding, so I'm certain my code is fairly incorrect. I think where my code starts functioning improperly is with the while loop.
EDIT: How do I make this method without using arrays or extra methods, like the split method?
public static String blankWords(String s1)
StringBuilder sb = new StringBuilder();
if(s1.length() > 2)
sb.append(s1.charAt(0));
for(int x = 1; x < s1.length() - 1; x = x + 1)
char y = ' ';
while(y != s1.charAt(x))
sb.append("_");
x = x + 1;
sb.append(s1.charAt(s1.length() - 1));
return sb.toString();
return s1;
What my code is outputting:
HW2.blankWords("This is a Test.")
java.lang.StringIndexOutOfBoundsException: String index out of range: 15
at java.lang.String.charAt(Unknown Source)
at HW2.blankWords(HW2.java:73)
What my code should output:
HW2.blankWords("This is a Test.")
"T__s is a T__t."
java
add a comment |
The purpose of this method is replace all but the first and last letters of each word with "_". I'm a complete novice when it comes to coding, so I'm certain my code is fairly incorrect. I think where my code starts functioning improperly is with the while loop.
EDIT: How do I make this method without using arrays or extra methods, like the split method?
public static String blankWords(String s1)
StringBuilder sb = new StringBuilder();
if(s1.length() > 2)
sb.append(s1.charAt(0));
for(int x = 1; x < s1.length() - 1; x = x + 1)
char y = ' ';
while(y != s1.charAt(x))
sb.append("_");
x = x + 1;
sb.append(s1.charAt(s1.length() - 1));
return sb.toString();
return s1;
What my code is outputting:
HW2.blankWords("This is a Test.")
java.lang.StringIndexOutOfBoundsException: String index out of range: 15
at java.lang.String.charAt(Unknown Source)
at HW2.blankWords(HW2.java:73)
What my code should output:
HW2.blankWords("This is a Test.")
"T__s is a T__t."
java
Well, thiswhile(y != s1.charAt(x))
can't work when the program already treats the last word. There is no more whitespace to exit the loop. So you need to add another exit condition.
– Tom
Mar 7 at 23:00
Do you know what StringIndexOutOfBoundsException means?
– Paul Wostenberg
Mar 7 at 23:03
When you say HW2.blankWords("This is a Test.") should output "T__s is a T__t.", do you mean to include that period? it doesn't look like your code makes any attempt to keep a period at the end of the sentence
– Asthmatic
Mar 7 at 23:11
@Tom i was drunk. Embarrasing. You were so right.
– aran
Mar 7 at 23:22
add a comment |
The purpose of this method is replace all but the first and last letters of each word with "_". I'm a complete novice when it comes to coding, so I'm certain my code is fairly incorrect. I think where my code starts functioning improperly is with the while loop.
EDIT: How do I make this method without using arrays or extra methods, like the split method?
public static String blankWords(String s1)
StringBuilder sb = new StringBuilder();
if(s1.length() > 2)
sb.append(s1.charAt(0));
for(int x = 1; x < s1.length() - 1; x = x + 1)
char y = ' ';
while(y != s1.charAt(x))
sb.append("_");
x = x + 1;
sb.append(s1.charAt(s1.length() - 1));
return sb.toString();
return s1;
What my code is outputting:
HW2.blankWords("This is a Test.")
java.lang.StringIndexOutOfBoundsException: String index out of range: 15
at java.lang.String.charAt(Unknown Source)
at HW2.blankWords(HW2.java:73)
What my code should output:
HW2.blankWords("This is a Test.")
"T__s is a T__t."
java
The purpose of this method is replace all but the first and last letters of each word with "_". I'm a complete novice when it comes to coding, so I'm certain my code is fairly incorrect. I think where my code starts functioning improperly is with the while loop.
EDIT: How do I make this method without using arrays or extra methods, like the split method?
public static String blankWords(String s1)
StringBuilder sb = new StringBuilder();
if(s1.length() > 2)
sb.append(s1.charAt(0));
for(int x = 1; x < s1.length() - 1; x = x + 1)
char y = ' ';
while(y != s1.charAt(x))
sb.append("_");
x = x + 1;
sb.append(s1.charAt(s1.length() - 1));
return sb.toString();
return s1;
What my code is outputting:
HW2.blankWords("This is a Test.")
java.lang.StringIndexOutOfBoundsException: String index out of range: 15
at java.lang.String.charAt(Unknown Source)
at HW2.blankWords(HW2.java:73)
What my code should output:
HW2.blankWords("This is a Test.")
"T__s is a T__t."
java
java
edited Mar 7 at 23:24
user11168053
asked Mar 7 at 22:56
user11168053user11168053
155
155
Well, thiswhile(y != s1.charAt(x))
can't work when the program already treats the last word. There is no more whitespace to exit the loop. So you need to add another exit condition.
– Tom
Mar 7 at 23:00
Do you know what StringIndexOutOfBoundsException means?
– Paul Wostenberg
Mar 7 at 23:03
When you say HW2.blankWords("This is a Test.") should output "T__s is a T__t.", do you mean to include that period? it doesn't look like your code makes any attempt to keep a period at the end of the sentence
– Asthmatic
Mar 7 at 23:11
@Tom i was drunk. Embarrasing. You were so right.
– aran
Mar 7 at 23:22
add a comment |
Well, thiswhile(y != s1.charAt(x))
can't work when the program already treats the last word. There is no more whitespace to exit the loop. So you need to add another exit condition.
– Tom
Mar 7 at 23:00
Do you know what StringIndexOutOfBoundsException means?
– Paul Wostenberg
Mar 7 at 23:03
When you say HW2.blankWords("This is a Test.") should output "T__s is a T__t.", do you mean to include that period? it doesn't look like your code makes any attempt to keep a period at the end of the sentence
– Asthmatic
Mar 7 at 23:11
@Tom i was drunk. Embarrasing. You were so right.
– aran
Mar 7 at 23:22
Well, this
while(y != s1.charAt(x))
can't work when the program already treats the last word. There is no more whitespace to exit the loop. So you need to add another exit condition.– Tom
Mar 7 at 23:00
Well, this
while(y != s1.charAt(x))
can't work when the program already treats the last word. There is no more whitespace to exit the loop. So you need to add another exit condition.– Tom
Mar 7 at 23:00
Do you know what StringIndexOutOfBoundsException means?
– Paul Wostenberg
Mar 7 at 23:03
Do you know what StringIndexOutOfBoundsException means?
– Paul Wostenberg
Mar 7 at 23:03
When you say HW2.blankWords("This is a Test.") should output "T__s is a T__t.", do you mean to include that period? it doesn't look like your code makes any attempt to keep a period at the end of the sentence
– Asthmatic
Mar 7 at 23:11
When you say HW2.blankWords("This is a Test.") should output "T__s is a T__t.", do you mean to include that period? it doesn't look like your code makes any attempt to keep a period at the end of the sentence
– Asthmatic
Mar 7 at 23:11
@Tom i was drunk. Embarrasing. You were so right.
– aran
Mar 7 at 23:22
@Tom i was drunk. Embarrasing. You were so right.
– aran
Mar 7 at 23:22
add a comment |
4 Answers
4
active
oldest
votes
Here is a pretty simple solution:
class Scratch
public static void main(String[] args)
System.out.println(blankWords("My name is sam orozco"));
public static String delim = "_";
public static String blankWords(String s1)
// this split arg on one or more space
String[] words = s1.split("\s+");
StringBuilder response = new StringBuilder();
for (String val : words)
val = convertWord(val);
response.append(val).append(" ");
return response.toString().trim();
public static String convertWord(String val)
int len = val.length();
StringBuilder bldr = new StringBuilder();
int index = 0;
for (char ch : val.toCharArray()) index == len - 1)
bldr.append(ch);
else
bldr.append(delim);
index++;
return bldr.toString();
add a comment |
You can do this using a StringTokenizer that will extract words based on a list of delimiters. Since you want to keep those delimiters in the output, you'll instruct the tokenizer to return them as tokens:
String blankWords(String s)
// build a tokenizer for your string, listing all special chars as delimiters. The last argument says that delimiters are going to be returned as tokens themselves (so we can include them in the output string)
StringTokenizer tokenizer = new StringTokenizer(s, " .,;:?!()[]", true);
// a helper class to build the output string; think of it as just a more efficient concat utility
StringBuilder sb = new StringBuilder();
while (tokenizer.hasMoreTokens())
String blankWord = blank(tokenizer.nextToken());
sb.append(blankWord);
return sb.toString();
/**
* Replaces all but the first and last characters in a string with '_'
*/
private String blank(String word)
// strings of up to two chars will be returned as such
// delimiters will always fall into this category, as they are always single characters
if (word.length() <= 2)
return word;
// no need to iterate through all chars, we'll just get the array
final char[] chars = word.toCharArray();
// fill the array of chars with '_', starting with position 1 (the second char) up to the last char (exclusive, i.e. last-but-one)
Arrays.fill(chars, 1, chars.length - 1, '_');
// build the resulting word based on the modified array of chars
return new String(chars);
Here is the contents of a test that validates this implementation, using TestNG:
@Test(dataProvider = "texts")
public void testBlankWords(String input, String expectedOutput)
assertEquals(blankWords(input), expectedOutput);
@DataProvider
public Object[][] texts()
return new Object[][]
"This is a test.", "T__s is a t__t.",
"This one, again, is (yet another) test!", "T__s o_e, a___n, is (y_t a_____r) t__t!"
;
The main drawback of this implementation is that StringTokenizer
requires you to list all the delimiters by hand. With a more advanced implementation, you can consider a delimiter any character that returns false
for Character.isAlphabetic(c)
or however you decide to define your non-word chars.
P.S.
This could be a "more advanced implementation", as I mentioned above:
static String blankWords(String text)
final char[] textChars = text.toCharArray();
int wordStart = -1; // keep track of the current word start position, -1 means no current word
for (int i = 0; i < textChars.length; i++)
if (!Character.isAlphabetic(textChars[i]))
if (wordStart >= 0)
for (int j = wordStart + 1; j < i - 1; j++)
textChars[j] = '_';
wordStart = -1; // reset the current word to none
else if (wordStart == -1)
wordStart = i; // alphabetic characters start a new word, when there's none started already
else if (i == textChars.length - 1) // if the last character is aplhabetic
for (int j = wordStart + 1; j < i; j++)
textChars[j] = '_';
return new String(textChars);
add a comment |
No while loop necessary!
Look ahead by 1 character to see if it's a space, or if the current character is a space, in that case you append it. Otherwise you make sure to add the next character (skipNext false).
Always add the last character
public static String blankWords(String s1)
StringBuilder sb = new StringBuilder();
if(s1.length() > 2)
Boolean skipNext = false;
for(int x = 0; x < s1.length() - 1; x = x + 1) s1.charAt(x + 1) == ' ')
sb.append(s1.charAt(x));
skipNext = false;
else
if(skipNext)
sb.append('_');
else
sb.append(s1.charAt(x));
skipNext = true;
sb.append(s1.charAt(s1.length() - 1));
return sb.toString();
return s1;
For input"This is a Test."
, that returns"T__s is a T___."
, but it is expected to return"T__s is a T__t."
. --- Instead of testing for space, reverse the check and test for letter, e.g. usingCharacter.isLetter(char ch)
.
– Andreas
Mar 7 at 23:16
add a comment |
For the more advanced programmer, use regular expression.
public static String blankWords(String s1)
return s1.replaceAll("\B\w\B", "_");
This correctly keeps the final t
, i.e. blankWords("This is a Test.")
returns "T__s is a T__t."
.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55054128%2fjava-programming-replace-all-but-first-and-last-letters-of-each-word-with%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
Here is a pretty simple solution:
class Scratch
public static void main(String[] args)
System.out.println(blankWords("My name is sam orozco"));
public static String delim = "_";
public static String blankWords(String s1)
// this split arg on one or more space
String[] words = s1.split("\s+");
StringBuilder response = new StringBuilder();
for (String val : words)
val = convertWord(val);
response.append(val).append(" ");
return response.toString().trim();
public static String convertWord(String val)
int len = val.length();
StringBuilder bldr = new StringBuilder();
int index = 0;
for (char ch : val.toCharArray()) index == len - 1)
bldr.append(ch);
else
bldr.append(delim);
index++;
return bldr.toString();
add a comment |
Here is a pretty simple solution:
class Scratch
public static void main(String[] args)
System.out.println(blankWords("My name is sam orozco"));
public static String delim = "_";
public static String blankWords(String s1)
// this split arg on one or more space
String[] words = s1.split("\s+");
StringBuilder response = new StringBuilder();
for (String val : words)
val = convertWord(val);
response.append(val).append(" ");
return response.toString().trim();
public static String convertWord(String val)
int len = val.length();
StringBuilder bldr = new StringBuilder();
int index = 0;
for (char ch : val.toCharArray()) index == len - 1)
bldr.append(ch);
else
bldr.append(delim);
index++;
return bldr.toString();
add a comment |
Here is a pretty simple solution:
class Scratch
public static void main(String[] args)
System.out.println(blankWords("My name is sam orozco"));
public static String delim = "_";
public static String blankWords(String s1)
// this split arg on one or more space
String[] words = s1.split("\s+");
StringBuilder response = new StringBuilder();
for (String val : words)
val = convertWord(val);
response.append(val).append(" ");
return response.toString().trim();
public static String convertWord(String val)
int len = val.length();
StringBuilder bldr = new StringBuilder();
int index = 0;
for (char ch : val.toCharArray()) index == len - 1)
bldr.append(ch);
else
bldr.append(delim);
index++;
return bldr.toString();
Here is a pretty simple solution:
class Scratch
public static void main(String[] args)
System.out.println(blankWords("My name is sam orozco"));
public static String delim = "_";
public static String blankWords(String s1)
// this split arg on one or more space
String[] words = s1.split("\s+");
StringBuilder response = new StringBuilder();
for (String val : words)
val = convertWord(val);
response.append(val).append(" ");
return response.toString().trim();
public static String convertWord(String val)
int len = val.length();
StringBuilder bldr = new StringBuilder();
int index = 0;
for (char ch : val.toCharArray()) index == len - 1)
bldr.append(ch);
else
bldr.append(delim);
index++;
return bldr.toString();
answered Mar 7 at 23:50
Sam OrozcoSam Orozco
929919
929919
add a comment |
add a comment |
You can do this using a StringTokenizer that will extract words based on a list of delimiters. Since you want to keep those delimiters in the output, you'll instruct the tokenizer to return them as tokens:
String blankWords(String s)
// build a tokenizer for your string, listing all special chars as delimiters. The last argument says that delimiters are going to be returned as tokens themselves (so we can include them in the output string)
StringTokenizer tokenizer = new StringTokenizer(s, " .,;:?!()[]", true);
// a helper class to build the output string; think of it as just a more efficient concat utility
StringBuilder sb = new StringBuilder();
while (tokenizer.hasMoreTokens())
String blankWord = blank(tokenizer.nextToken());
sb.append(blankWord);
return sb.toString();
/**
* Replaces all but the first and last characters in a string with '_'
*/
private String blank(String word)
// strings of up to two chars will be returned as such
// delimiters will always fall into this category, as they are always single characters
if (word.length() <= 2)
return word;
// no need to iterate through all chars, we'll just get the array
final char[] chars = word.toCharArray();
// fill the array of chars with '_', starting with position 1 (the second char) up to the last char (exclusive, i.e. last-but-one)
Arrays.fill(chars, 1, chars.length - 1, '_');
// build the resulting word based on the modified array of chars
return new String(chars);
Here is the contents of a test that validates this implementation, using TestNG:
@Test(dataProvider = "texts")
public void testBlankWords(String input, String expectedOutput)
assertEquals(blankWords(input), expectedOutput);
@DataProvider
public Object[][] texts()
return new Object[][]
"This is a test.", "T__s is a t__t.",
"This one, again, is (yet another) test!", "T__s o_e, a___n, is (y_t a_____r) t__t!"
;
The main drawback of this implementation is that StringTokenizer
requires you to list all the delimiters by hand. With a more advanced implementation, you can consider a delimiter any character that returns false
for Character.isAlphabetic(c)
or however you decide to define your non-word chars.
P.S.
This could be a "more advanced implementation", as I mentioned above:
static String blankWords(String text)
final char[] textChars = text.toCharArray();
int wordStart = -1; // keep track of the current word start position, -1 means no current word
for (int i = 0; i < textChars.length; i++)
if (!Character.isAlphabetic(textChars[i]))
if (wordStart >= 0)
for (int j = wordStart + 1; j < i - 1; j++)
textChars[j] = '_';
wordStart = -1; // reset the current word to none
else if (wordStart == -1)
wordStart = i; // alphabetic characters start a new word, when there's none started already
else if (i == textChars.length - 1) // if the last character is aplhabetic
for (int j = wordStart + 1; j < i; j++)
textChars[j] = '_';
return new String(textChars);
add a comment |
You can do this using a StringTokenizer that will extract words based on a list of delimiters. Since you want to keep those delimiters in the output, you'll instruct the tokenizer to return them as tokens:
String blankWords(String s)
// build a tokenizer for your string, listing all special chars as delimiters. The last argument says that delimiters are going to be returned as tokens themselves (so we can include them in the output string)
StringTokenizer tokenizer = new StringTokenizer(s, " .,;:?!()[]", true);
// a helper class to build the output string; think of it as just a more efficient concat utility
StringBuilder sb = new StringBuilder();
while (tokenizer.hasMoreTokens())
String blankWord = blank(tokenizer.nextToken());
sb.append(blankWord);
return sb.toString();
/**
* Replaces all but the first and last characters in a string with '_'
*/
private String blank(String word)
// strings of up to two chars will be returned as such
// delimiters will always fall into this category, as they are always single characters
if (word.length() <= 2)
return word;
// no need to iterate through all chars, we'll just get the array
final char[] chars = word.toCharArray();
// fill the array of chars with '_', starting with position 1 (the second char) up to the last char (exclusive, i.e. last-but-one)
Arrays.fill(chars, 1, chars.length - 1, '_');
// build the resulting word based on the modified array of chars
return new String(chars);
Here is the contents of a test that validates this implementation, using TestNG:
@Test(dataProvider = "texts")
public void testBlankWords(String input, String expectedOutput)
assertEquals(blankWords(input), expectedOutput);
@DataProvider
public Object[][] texts()
return new Object[][]
"This is a test.", "T__s is a t__t.",
"This one, again, is (yet another) test!", "T__s o_e, a___n, is (y_t a_____r) t__t!"
;
The main drawback of this implementation is that StringTokenizer
requires you to list all the delimiters by hand. With a more advanced implementation, you can consider a delimiter any character that returns false
for Character.isAlphabetic(c)
or however you decide to define your non-word chars.
P.S.
This could be a "more advanced implementation", as I mentioned above:
static String blankWords(String text)
final char[] textChars = text.toCharArray();
int wordStart = -1; // keep track of the current word start position, -1 means no current word
for (int i = 0; i < textChars.length; i++)
if (!Character.isAlphabetic(textChars[i]))
if (wordStart >= 0)
for (int j = wordStart + 1; j < i - 1; j++)
textChars[j] = '_';
wordStart = -1; // reset the current word to none
else if (wordStart == -1)
wordStart = i; // alphabetic characters start a new word, when there's none started already
else if (i == textChars.length - 1) // if the last character is aplhabetic
for (int j = wordStart + 1; j < i; j++)
textChars[j] = '_';
return new String(textChars);
add a comment |
You can do this using a StringTokenizer that will extract words based on a list of delimiters. Since you want to keep those delimiters in the output, you'll instruct the tokenizer to return them as tokens:
String blankWords(String s)
// build a tokenizer for your string, listing all special chars as delimiters. The last argument says that delimiters are going to be returned as tokens themselves (so we can include them in the output string)
StringTokenizer tokenizer = new StringTokenizer(s, " .,;:?!()[]", true);
// a helper class to build the output string; think of it as just a more efficient concat utility
StringBuilder sb = new StringBuilder();
while (tokenizer.hasMoreTokens())
String blankWord = blank(tokenizer.nextToken());
sb.append(blankWord);
return sb.toString();
/**
* Replaces all but the first and last characters in a string with '_'
*/
private String blank(String word)
// strings of up to two chars will be returned as such
// delimiters will always fall into this category, as they are always single characters
if (word.length() <= 2)
return word;
// no need to iterate through all chars, we'll just get the array
final char[] chars = word.toCharArray();
// fill the array of chars with '_', starting with position 1 (the second char) up to the last char (exclusive, i.e. last-but-one)
Arrays.fill(chars, 1, chars.length - 1, '_');
// build the resulting word based on the modified array of chars
return new String(chars);
Here is the contents of a test that validates this implementation, using TestNG:
@Test(dataProvider = "texts")
public void testBlankWords(String input, String expectedOutput)
assertEquals(blankWords(input), expectedOutput);
@DataProvider
public Object[][] texts()
return new Object[][]
"This is a test.", "T__s is a t__t.",
"This one, again, is (yet another) test!", "T__s o_e, a___n, is (y_t a_____r) t__t!"
;
The main drawback of this implementation is that StringTokenizer
requires you to list all the delimiters by hand. With a more advanced implementation, you can consider a delimiter any character that returns false
for Character.isAlphabetic(c)
or however you decide to define your non-word chars.
P.S.
This could be a "more advanced implementation", as I mentioned above:
static String blankWords(String text)
final char[] textChars = text.toCharArray();
int wordStart = -1; // keep track of the current word start position, -1 means no current word
for (int i = 0; i < textChars.length; i++)
if (!Character.isAlphabetic(textChars[i]))
if (wordStart >= 0)
for (int j = wordStart + 1; j < i - 1; j++)
textChars[j] = '_';
wordStart = -1; // reset the current word to none
else if (wordStart == -1)
wordStart = i; // alphabetic characters start a new word, when there's none started already
else if (i == textChars.length - 1) // if the last character is aplhabetic
for (int j = wordStart + 1; j < i; j++)
textChars[j] = '_';
return new String(textChars);
You can do this using a StringTokenizer that will extract words based on a list of delimiters. Since you want to keep those delimiters in the output, you'll instruct the tokenizer to return them as tokens:
String blankWords(String s)
// build a tokenizer for your string, listing all special chars as delimiters. The last argument says that delimiters are going to be returned as tokens themselves (so we can include them in the output string)
StringTokenizer tokenizer = new StringTokenizer(s, " .,;:?!()[]", true);
// a helper class to build the output string; think of it as just a more efficient concat utility
StringBuilder sb = new StringBuilder();
while (tokenizer.hasMoreTokens())
String blankWord = blank(tokenizer.nextToken());
sb.append(blankWord);
return sb.toString();
/**
* Replaces all but the first and last characters in a string with '_'
*/
private String blank(String word)
// strings of up to two chars will be returned as such
// delimiters will always fall into this category, as they are always single characters
if (word.length() <= 2)
return word;
// no need to iterate through all chars, we'll just get the array
final char[] chars = word.toCharArray();
// fill the array of chars with '_', starting with position 1 (the second char) up to the last char (exclusive, i.e. last-but-one)
Arrays.fill(chars, 1, chars.length - 1, '_');
// build the resulting word based on the modified array of chars
return new String(chars);
Here is the contents of a test that validates this implementation, using TestNG:
@Test(dataProvider = "texts")
public void testBlankWords(String input, String expectedOutput)
assertEquals(blankWords(input), expectedOutput);
@DataProvider
public Object[][] texts()
return new Object[][]
"This is a test.", "T__s is a t__t.",
"This one, again, is (yet another) test!", "T__s o_e, a___n, is (y_t a_____r) t__t!"
;
The main drawback of this implementation is that StringTokenizer
requires you to list all the delimiters by hand. With a more advanced implementation, you can consider a delimiter any character that returns false
for Character.isAlphabetic(c)
or however you decide to define your non-word chars.
P.S.
This could be a "more advanced implementation", as I mentioned above:
static String blankWords(String text)
final char[] textChars = text.toCharArray();
int wordStart = -1; // keep track of the current word start position, -1 means no current word
for (int i = 0; i < textChars.length; i++)
if (!Character.isAlphabetic(textChars[i]))
if (wordStart >= 0)
for (int j = wordStart + 1; j < i - 1; j++)
textChars[j] = '_';
wordStart = -1; // reset the current word to none
else if (wordStart == -1)
wordStart = i; // alphabetic characters start a new word, when there's none started already
else if (i == textChars.length - 1) // if the last character is aplhabetic
for (int j = wordStart + 1; j < i; j++)
textChars[j] = '_';
return new String(textChars);
edited Mar 8 at 14:55
answered Mar 7 at 23:53
Costi CiudatuCosti Ciudatu
28.3k54582
28.3k54582
add a comment |
add a comment |
No while loop necessary!
Look ahead by 1 character to see if it's a space, or if the current character is a space, in that case you append it. Otherwise you make sure to add the next character (skipNext false).
Always add the last character
public static String blankWords(String s1)
StringBuilder sb = new StringBuilder();
if(s1.length() > 2)
Boolean skipNext = false;
for(int x = 0; x < s1.length() - 1; x = x + 1) s1.charAt(x + 1) == ' ')
sb.append(s1.charAt(x));
skipNext = false;
else
if(skipNext)
sb.append('_');
else
sb.append(s1.charAt(x));
skipNext = true;
sb.append(s1.charAt(s1.length() - 1));
return sb.toString();
return s1;
For input"This is a Test."
, that returns"T__s is a T___."
, but it is expected to return"T__s is a T__t."
. --- Instead of testing for space, reverse the check and test for letter, e.g. usingCharacter.isLetter(char ch)
.
– Andreas
Mar 7 at 23:16
add a comment |
No while loop necessary!
Look ahead by 1 character to see if it's a space, or if the current character is a space, in that case you append it. Otherwise you make sure to add the next character (skipNext false).
Always add the last character
public static String blankWords(String s1)
StringBuilder sb = new StringBuilder();
if(s1.length() > 2)
Boolean skipNext = false;
for(int x = 0; x < s1.length() - 1; x = x + 1) s1.charAt(x + 1) == ' ')
sb.append(s1.charAt(x));
skipNext = false;
else
if(skipNext)
sb.append('_');
else
sb.append(s1.charAt(x));
skipNext = true;
sb.append(s1.charAt(s1.length() - 1));
return sb.toString();
return s1;
For input"This is a Test."
, that returns"T__s is a T___."
, but it is expected to return"T__s is a T__t."
. --- Instead of testing for space, reverse the check and test for letter, e.g. usingCharacter.isLetter(char ch)
.
– Andreas
Mar 7 at 23:16
add a comment |
No while loop necessary!
Look ahead by 1 character to see if it's a space, or if the current character is a space, in that case you append it. Otherwise you make sure to add the next character (skipNext false).
Always add the last character
public static String blankWords(String s1)
StringBuilder sb = new StringBuilder();
if(s1.length() > 2)
Boolean skipNext = false;
for(int x = 0; x < s1.length() - 1; x = x + 1) s1.charAt(x + 1) == ' ')
sb.append(s1.charAt(x));
skipNext = false;
else
if(skipNext)
sb.append('_');
else
sb.append(s1.charAt(x));
skipNext = true;
sb.append(s1.charAt(s1.length() - 1));
return sb.toString();
return s1;
No while loop necessary!
Look ahead by 1 character to see if it's a space, or if the current character is a space, in that case you append it. Otherwise you make sure to add the next character (skipNext false).
Always add the last character
public static String blankWords(String s1)
StringBuilder sb = new StringBuilder();
if(s1.length() > 2)
Boolean skipNext = false;
for(int x = 0; x < s1.length() - 1; x = x + 1) s1.charAt(x + 1) == ' ')
sb.append(s1.charAt(x));
skipNext = false;
else
if(skipNext)
sb.append('_');
else
sb.append(s1.charAt(x));
skipNext = true;
sb.append(s1.charAt(s1.length() - 1));
return sb.toString();
return s1;
answered Mar 7 at 23:09
AsthmaticAsthmatic
1,025619
1,025619
For input"This is a Test."
, that returns"T__s is a T___."
, but it is expected to return"T__s is a T__t."
. --- Instead of testing for space, reverse the check and test for letter, e.g. usingCharacter.isLetter(char ch)
.
– Andreas
Mar 7 at 23:16
add a comment |
For input"This is a Test."
, that returns"T__s is a T___."
, but it is expected to return"T__s is a T__t."
. --- Instead of testing for space, reverse the check and test for letter, e.g. usingCharacter.isLetter(char ch)
.
– Andreas
Mar 7 at 23:16
For input
"This is a Test."
, that returns "T__s is a T___."
, but it is expected to return "T__s is a T__t."
. --- Instead of testing for space, reverse the check and test for letter, e.g. using Character.isLetter(char ch)
.– Andreas
Mar 7 at 23:16
For input
"This is a Test."
, that returns "T__s is a T___."
, but it is expected to return "T__s is a T__t."
. --- Instead of testing for space, reverse the check and test for letter, e.g. using Character.isLetter(char ch)
.– Andreas
Mar 7 at 23:16
add a comment |
For the more advanced programmer, use regular expression.
public static String blankWords(String s1)
return s1.replaceAll("\B\w\B", "_");
This correctly keeps the final t
, i.e. blankWords("This is a Test.")
returns "T__s is a T__t."
.
add a comment |
For the more advanced programmer, use regular expression.
public static String blankWords(String s1)
return s1.replaceAll("\B\w\B", "_");
This correctly keeps the final t
, i.e. blankWords("This is a Test.")
returns "T__s is a T__t."
.
add a comment |
For the more advanced programmer, use regular expression.
public static String blankWords(String s1)
return s1.replaceAll("\B\w\B", "_");
This correctly keeps the final t
, i.e. blankWords("This is a Test.")
returns "T__s is a T__t."
.
For the more advanced programmer, use regular expression.
public static String blankWords(String s1)
return s1.replaceAll("\B\w\B", "_");
This correctly keeps the final t
, i.e. blankWords("This is a Test.")
returns "T__s is a T__t."
.
edited Mar 7 at 23:22
answered Mar 7 at 23:17
AndreasAndreas
79.6k465129
79.6k465129
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55054128%2fjava-programming-replace-all-but-first-and-last-letters-of-each-word-with%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Well, this
while(y != s1.charAt(x))
can't work when the program already treats the last word. There is no more whitespace to exit the loop. So you need to add another exit condition.– Tom
Mar 7 at 23:00
Do you know what StringIndexOutOfBoundsException means?
– Paul Wostenberg
Mar 7 at 23:03
When you say HW2.blankWords("This is a Test.") should output "T__s is a T__t.", do you mean to include that period? it doesn't look like your code makes any attempt to keep a period at the end of the sentence
– Asthmatic
Mar 7 at 23:11
@Tom i was drunk. Embarrasing. You were so right.
– aran
Mar 7 at 23:22