Remove Whitespaces ONLY at the end of a String (java) [duplicate] - java

This question already has answers here:
How to remove only trailing spaces of a string in Java and keep leading spaces?
(10 answers)
Closed 5 years ago.
i already found similar topics but they were not really helpful.
I basically need to know how I can remove whitespaces ONLY at the end of a string.
For example: String a = "Good Morning it is a nice day ";
Should be: String a = "Good Morning it is a nice day";
You see there are like three whitespaces at the end or something. I got replaceAll() as a suggestion but as I said I only want to remove the remaining whitespaces at the end. How do I do that ? I already tried different things like going through the String like this:
for(int i = a.length(); i > a.length() - 3; i++){
if(a.charAt(i) == ' '){
<insert Solution here>
}
}
With the code above I wanted to check the last three Chars of the string because it is sufficient. It is sufficient for the stuff I want to do. There wont be a case with 99+ whitespaces at the end (probably).
But as you see I still dont know which method to use or if this is actually the right way.
Any suggestions please ?

If your goal is to cut only the trailing white space characters and to save leading white space characters of your String, you can use String class' replaceFirst() method:
String yourString = " my text. ";
String cutTrailingWhiteSpaceCharacters = yourString.replaceFirst("\\s++$", "");
\\s++ - one or more white space characters (use of possesive quantifiers (take a look at Pattern class in the Java API documentation, you have listed all of the special characters used in reguĊ‚ar expressions there)),
$ - end of string
You might also want to take a look at part of my answer before the edit:
If you don't care about the leading white space characters of your input String:
String class provides a trim() method. It might be quick solution in your case as it cuts leading and trailing whitespaces of the given String.

You can either use the regular expression:
a = a.replaceAll("\\s+$", "");
to remove trailing whitespaces and store the result back into a
or using a for loop:
String a = "Good Morning it is a nice day ";
StringBuilder temp = new StringBuilder(a);
for( int i = temp.length() - 1 ; i >= 0; i--){
if(temp.charAt(i) == ' '){
temp.deleteCharAt(i);
}else{
break;
}
}
a = temp.toString();

a = ("X" + a).trim().substring(1);

int counter = 0;
String newWord = "";
for(int i = 0; i < word.length(); i++){
if (word.charAt(i) == " "){
counter++;
}
else {
counter = 0;
}
if (counter > 1){
newWord = word.substring(0, i);
break;
}
else {
newWord = word;
}
}
The solution would look something like this.

Related

Replace extra spaces in string with a single space in Java, without regex

I want to basically to do this:
String secondString = firstString.trim().replaceAll(" +", " ");
Or replace all the multiple spaces in my string, with just a single space. However, is it possibly to do this without regex like I am doing here?
Thanks!
However, is it possibly to do this without regex like I am doing here?
Yes. The regular expression is clear and easy to read, so I would probably use that; but you could use a nested loop, a StringBuilder and Character.isWhitespace(char) like
StringBuilder sb = new StringBuilder();
for (int i = 0; i < firstString.length(); i++) {
sb.append(firstString.charAt(i));
if (Character.isWhitespace(firstString.charAt(i))) {
// The current character is white space, skip characters until
// the next character is not.
while (i + 1 < firstString.length()
&& Character.isWhitespace(firstString.charAt(i + 1))) {
i++;
}
}
}
String secondString = sb.toString();
Note: This is a rare example of a nested loop that is O(N); the inner loop modifies the same counter as the outer loop.

Java adding modified tokens into string

I currently have a program that individually converts tokens of a string into their piglatin counterparts. However, the program needs to insert them back into the string they were taken with, with ALL of the original characters in it.
Hasta la vista baby. - the Terminator.
Hasta
astaHay
la
alay
vista
istavay
baby
abybay
the
ethay
Terminator
erminatorTay
These are all of the words and their conversions. I tried a method directly placing them back in, however accounting for missing characters and different length made it hard for me to do that. I tried to insert characters based on the length of each token added up, but that ran into complications when there were more than 1 whitespace character. How would I insert these words back into the string so it looks like this:
Astahay alay istavay abybay. - ethay Erminatortay
PigOrig = key.readLine();
String[] PigSplit = PigOrig.split("\\W+");
for(int i = 0; i < PigSplit.length; i++)
{
if(PigSplit[i] != null)
{
FinalStr += Piggy.vowelOut(PigSplit[i]); // VowelOut returns the converted word only, no trailing whitespace or punctuation
lengthtot += PigSplit[i].length();
FinalStr += PigOrig.charAt(lengthtot); // attempt at adding up the words and inserting the original punctuation that was in the string PigOrig
lengthtot ++;
}
}
If I understand your question, it is 'how do I replace each word with its translation in a string?' The simplest way is to use String.replace.
So if you have created a translate method then you could do something like:
String line = key.readLine();
for (String word: line.split("\\W+"))
line = line.replace(word, translate(word));
The advantage of this approach is that you are replacing the words in the original string not putting the words back together again.
Also note that it might be easier to translate just using pattern matching. For example:
private String translate(String word) {
Matcher match = Pattern.compile("(\\w*)([aeiou]\\w*)").match(word);
if (match.matches())
return match.group(2) + match.group(1) + "ay";
else
return word;
}
If I understand correctly that you want to translate all the words in the input, my taste would be for building the new string from scratch:
String pigOrig = key.readLine();
String[] pigSplit = pigOrig.split("\\W+");
StringBuilder buf = new StringBuilder(pigOrig.length());
buf.append(translateWord(pigSplit[0]));
for(int i = 1; i < pigSplit.length; i++) {
buf.append(' ');
buf.append(translateWord(pigSplit[i]));
}
String result = buf.toString();

How to preserve the punctuation when converting words to Pig Latin?

I've been working on a Java program to convert English words to Pig Latin. I've done all the basic rules such as appending -ay, -way, etc., and special cases like question -> estionquay, rhyme -> ymerhay, and I also dealt with capitalization (Thomas -> Omasthay). However, I have one problem that I can't seem to solve: I need to preserve before-and-after punctuation. For example, What? -> Atwhay? Oh!->Ohway! "hello" -> "ellohay" and "Hello!" -> "Ellohay!" This is not a duplicate by the way, I've checked tons of pig latin questions and I cannot seem to figure out how to do it.
Here is my code so far (I've removed all the punctuation but can't figure out how to put it back in):
public static String scrub(String s)
{
String punct = ".,?!:;\"(){}[]<>";
String temp = "";
String pigged = "";
int index, index1, index2, index3 = 0;
for(int i = 0; i < s.length(); i++)
{
if(punct.indexOf(s.charAt(i)) == -1) //if s has no punctuation
{
temp+= s.charAt(i);
}
} //temp equals word without punctuation
pigged = pig(temp); //pig is the piglatin-translator method that I have already written,
//didn't want to put it here because it's almost 200 lines
for(int x = 0; x < s.length(); x++)
{
if(s.indexOf(punct)!= -1)//punctuation exists
{
index = x;
}
}
}
I get that in theory you could search the string for punctuation and that it should be near the beginning or end, so you would have to store the index and replace it after it is "piglatenized", but I keep getting confused about the for loop part. if you do index = x inside the for-loop, you're just replacing index every time the loop runs.
Help would be appreciated greatly! Also, please keep in mind I can't use shortcuts, I can use String methods and such but not things like Collections or ArrayLists (not that you'd need them here), I have to reinvent the wheel, basically. By the way, in case it wasn't clear, I already have the translating-to-piglatin thing down. I only need to preserve the punctuation before and after translating.
If you are allowed to use regular expressions, you can use the following code.
String pigSentence(String sentence) {
Matcher m = Pattern.compile("\\p{L}+").matcher(sentence);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(pig(m.group()));
}
m.appendTail();
return sb.toString();
}
In plain English, the above code is:
for each word in the sentence:
replace it with pig(word)
But if regular expressions are forbidden, you can try this:
String pigSentence(String sentence) {
char[] chars = sentence.toCharArray();
int i = 0, len = chars.length;
StringBuilder sb = new StringBuilder();
while (i < len) {
while (i < len && !Character.isLetter(chars[i]))
sb.append(chars[i++]);
int wordStart = i;
while (i < len && Character.isLetter(chars[i]))
i++;
int wordEnd = i;
if (wordStart != wordEnd) {
String word = sentence.substring(wordStart, wordEnd - wordStart);
sb.append(pig(word));
}
}
return sb.toString();
}
What you need to do is: remove punctuation if it exists, convert to pig latin, add punctuation back.
Assuming punctuation is always and the end of the string, You can check for punctuation with the following:
String punctuation = "";
for (int i = str.length() - 1; i > 0; i--) {
if (!Character.isLetter(str.charAt(i))) {
punctuation = str.charAt(i) + punctuation;
} else {
break; // Found all punctuation
}
}
str = str.substring(0, str.length() - punctuation.length()); // Remove punctuation
// Convert str to pig latin
// Append punctuation to str
I'd find it troublesome to handle punctuation separate from the translation. For punctuation at the very beginning or very end, you can save them and tag them back on after translating.
But if you remove the punctuations from the middle of the word, it will be rather difficult to replace them back to their correct location. Their indices change from the original word to the pigged word, and by a variable amount. (For some a random example, consider "Hel'lo" and "Quest'ion". The apostrophe shifts left by either 1 or 2, and you won't know which.)
How does your translation method handle punctuation? Do you really need to remove all punctuation before passing it to the translator? I'd suggest having your pigging method handle at least the punctuation in the middle of the word.

String manipulation of function names

For this Kata, i am given random function names in the PEP8 format and i am to convert them to camelCase.
(input)get_speed == (output)getSpeed ....
(input)set_distance == (output)setDistance
I have a understanding on one way of doing this written in pseudo-code:
loop through the word,
if the letter is an underscore
then delete the underscore
then get the next letter and change to a uppercase
endIf
endLoop
return the resultant word
But im unsure the best way of doing this, would it be more efficient to create a char array and loop through the element and then when it comes to finding an underscore delete that element and get the next index and change to uppercase.
Or would it be better to use recursion:
function camelCase takes a string
if the length of the string is 0,
then return the string
endIf
if the character is a underscore
then change to nothing,
then find next character and change to uppercase
return the string taking away the character
endIf
finally return the function taking the first character away
Any thoughts please, looking for a good efficient way of handing this problem. Thanks :)
I would go with this:
divide given String by underscore to array
from second word until end take first letter and convert it to uppercase
join to one word
This will work in O(n) (go through all names 3 time). For first case, use this function:
str.split("_");
for uppercase use this:
String newName = substring(0, 1).toUpperCase() + stre.substring(1);
But make sure you check size of the string first...
Edited - added implementation
It would look like this:
public String camelCase(String str) {
if (str == null ||str.trim().length() == 0) return str;
String[] split = str.split("_");
String newStr = split[0];
for (int i = 1; i < split.length; i++) {
newStr += split[i].substring(0, 1).toUpperCase() + split[i].substring(1);
}
return newStr;
}
for inputs:
"test"
"test_me"
"test_me_twice"
it returns:
"test"
"testMe"
"testMeTwice"
It would be simpler to iterate over the string instead of recursing.
String pep8 = "do_it_again";
StringBuilder camelCase = new StringBuilder();
for(int i = 0, l = pep8.length(); i < l; ++i) {
if(pep8.charAt(i) == '_' && (i + 1) < l) {
camelCase.append(Character.toUpperCase(pep8.charAt(++i)));
} else {
camelCase.append(pep8.charAt(i));
}
}
System.out.println(camelCase.toString()); // prints doItAgain
The question you pose is whether to use an iterative or a recursive approach. For this case I'd go for the recursive approach because it's straightforward, easy to understand doesn't require much resources (only one array, no new stackframe etc), though that doesn't really matter for this example.
Recursion is good for divide-and-conquer problems, but I don't see that fitting the case well, although it's possible.
An iterative implementation of the algorithm you described could look like the following:
StringBuilder buf = new StringBuilder(input);
for(int i = 0; i < buf.length(); i++){
if(buf.charAt(i) == '_'){
buf.deleteCharAt(i);
if(i != buf.length()){ //check fo EOL
buf.setCharAt(i, Character.toUpperCase(buf.charAt(i)));
}
}
}
return buf.toString();
The check for the EOL is not part of the given algorithm and could be ommitted, if the input string never ends with '_'

Formatting String Array efficiently in Java

I was working on some string formatting, and I was curious if I was doing it the most efficient way.
Assume I have a String Array:
String ArrayOne[] = {"/test/" , "/this/is/test" , "/that/is/" "/random/words" }
I want the result Array to be
String resultArray[] = {"test", "this_is_test" , "that_is" , "random_words" }
It's quite messy and brute-force-like.
for(char c : ArrayOne[i].toCharArray()) {
if(c == '/'){
occurances[i]++;
}
}
First I count the number of "/" in each String like above and then using these counts, I find the indexOf("/") for each string and add "_" accordingly.
As you can see though, it gets very messy.
Is there a more efficient way to do this besides the brute-force way I'm doing?
Thanks!
You could use replaceAll and replace, as follows:
String resultArray[] = new String[ArrayOne.length];
for (int i = 0; i < ArrayOne.length; ++i) {
resultArray[i] = ArrayOne[i].replaceAll("^/|/$", "").replace('/', '_');
}
The replaceAll method searches the string for a match to the regex given in the first argument, and replaces each match with the text in the second argument.
Here, we use it first to remove leading and trailing slashes. We search for slashes at the start of the string (^/) or the end of the string (/$), and replace them with nothing.
Then, we replace all remaining slashes with underscores using replace.

Categories

Resources