How to print the middle three characters of a String in Java? - java

I am new to programming and working on a Java String assignment. The question says:
Declare a variable of type String named middle3 (put your declaration with the other declarations near the top of the program) and use an assignment statement and thesubstring method to assign middle3 the substring consisting of the middle three characters of phrase (the character at the middle index together with the character to the left of that and the one to the right). Add a println statement to print out the result. Save, compile, and run to test what you have done so far.
Here is what I have done:
String phrase = new String ("This is a String test.");
String middle3 = new String ("tri"); //I want to print the middle 3 characters in "phrase" which I think is "tri".
middle3 = phrase.substring (9, 11); // this only prints out 1 letter instead of 3
System.out.println ("middle3: " + middle3);
Here is my output:
Original phrase: This is a String test.
Length of the phrase: 18 characters
middle3: S
I also think that there are 18 characters in the string "phrase", but if there isn't, please let me know. Thank you in advance for all your help!

Think about how to retrieve the middle 3 characters without hardcoding the bounds of the substring() method. You can use the length() method in this regard. For example, the middle character of a string of odd length will always be at index str.length()/2, while the two middle characters of a string of even length will always be at index str.length()/2 and (str.length()/2) - 1. So the definition of the three middle characters will be up to you. But for our sakes, we'll just make the 3 middle characters at indexes (str.length()/2)-1, str.length()/2, and (str.length()/2)+1. With this information you can modify this line of code you had before,
middle3 = phrase.substring (9, 11);
to
middle3 = phrase.substring (phrase.length()/2 - 1, phrase.length()/2 + 2);
As to why the original line of code you had before was returning only one letter, it has to do with the parameters of the substring method. The first parameter is inclusive, but the second parameter isn't. Therefore, you were only retrieving characters from 9 to 10.
This is a String test.
^^^
9,10,11 (11 is not included)
The three characters I pointed to are at indices 9, 10, and 11 respectively. You only retrieved the chars ' ' and 'S', which together is just " S". That explains the one-letter output before.

First off, there are 22 characters in phrase.
"This is a String test."
^^^^^^^^^^^^^^^^^^^^^^ --> 22
Note that spaces () count towards the character count. Additionally, String has a method length() which will give you this number.
String phrase = "This is a String test.";
int phraseLength = phrase.length(); //22
From there, we can get the middle three characters by working off of the value phraseLength/2. The middle three characters would start one before the middle position, and stop one afterwards. However, because the string(int, int) method takes the end index to be exclusive, we should increase it by one.
String phrase = "This is a String test.";
int phraseLength = phrase.length(); //22
String middle3 = phrase.substring(phraseLength/2 - 1, phraseLength/2 + 2); // will have the middle 3 chars.
If the length of phrase is odd, this will return it middle 3 chars. If the length of phrase is even (as it is here), this will return the left-middle 3 chars. (For example, in 1,2,3,4, I'm using left-middle to represent 2 and right-middle to represent 3).
Another note, it's both unnecessary and bad practice to write new String("asdf"). Simply use the string literal instead.
String phrase = new String ("This is a String test."); //Bad
String phrase = "This is a String test."; //Good

you have an error in the begind index and the end index in the string, this is the correct code:
String phrase = new String("This is a String test.");
String middle3 = phrase.substring(11, 14);
System.out.println("middle3: " + middle3);

Related

Does trim() method removes CRLF characters also?

Suddenly noticed that trim() method removes CRLF - new line - characters also..:
String s = "str\r\n";
s = s.trim();
System.out.println("--");
System.out.print(s);
System.out.println("--");
Is it intended to do so?
Yes, see the doc:
Otherwise, let k be the index of the first character in the string
whose code is greater than '\u0020', and let m be the index of the
last character in the string whose code is greater than '\u0020'. A
new String object is created, representing the substring of this
string that begins with the character at index k and ends with the
character at index m-that is, the result of this.substring(k, m+1).
CR+LF: CR (U+000D) followed by LF (U+000A) less than U+0020

Explain the Code and why Subtract the substring

public boolean frontAgain(String str)
{
int len = str.length();
if(len >= 2)
return str.substring(0, 2).equals(str.substring(len-2, len));
else
return false;
}
Can someone please explain why the second substring statement using a word example and a step by step analysis. The program checks if first two letters match the last two letters. for example the word was edited.
str.substring(len-2, len) asks for the last two letters of a string.
To get the last two letters, you need the beginning value of the substring to be the length (5) minus 2 characters, which gives you 3. This is because indexes in Java start at 0. For example, the positions for the characters in the string "horse" are 01234 (i.e. "h" is at index 0, "o" is at index 1 etc.), and the length is 5.
The second parameter of String.subString is for the ending index, which is exclusive. This means the first character position that is not part of the substring you want. In this case, it would be the length because that is 1 character higher than the end of the string.
If you put all that together, you get the following:
String str = "horse"
int length = str.length() // 5
String lastTwoChars = str.substring(length-2, length); // from position 3 to 5
System.out.println(lastTwoChars); // would show you "se"
The documentation for String.substring.

How to return only first n number of words in a sentence Java

Say i have a simple sentence as below.
For example, this is what have:
A simple sentence consists of only one clause. A compound sentence
consists of two or more independent clauses. A complex sentence has at
least one independent clause plus at least one dependent clause. A set
of words with no independent clause may be an incomplete sentence,
also called a sentence fragment.
I want only first 10 words in the sentence above.
I'm trying to produce the following string:
A simple sentence consists of only one clause. A compound
I tried this:
bigString.split(" " ,10).toString()
But it returns the same bigString wrapped with [] array.
Thanks in advance.
Assume bigString : String equals your text. First thing you want to do is split the string in single words.
String[] words = bigString.split(" ");
How many words do you like to extract?
int n = 10;
Put words together
String newString = "";
for (int i = 0; i < n; i++) { newString = newString + " " + words[i];}
System.out.println(newString);
Hope this is what you needed.
If you want to know more about regular expressions (i.e. to tell java where to split), see here: How to split a string in Java
If you use the split-Method with a limiter (yours is 10) it won't just give you the first 10 parts and stop but give you the first 9 parts and the 10th place of the array contains the rest of the input String. ToString concatenates all Strings from the array resulting in the whole input String. What you can do to achieve what you initially wanted is:
String[] myArray = bigString.split(" " ,11);
myArray[10] = ""; //setting the rest to an empty String
myArray.toString(); //This should give you now what you wanted but surrouned with array so just cut that off iterating the array instead of toString or something.
This will help you
String[] strings = Arrays.stream(bigstring.split(" "))
.limit(10)
.toArray(String[]::new);
Here is exactly what you want:
String[] result = new String[10];
// regex \s matches a whitespace character: [ \t\n\x0B\f\r]
String[] raw = bigString.split("\\s", 11);
// the last entry of raw array is the whole sentence, need to be trimmed.
System.arraycopy(raw, 0, result , 0, 10);
System.out.println(Arrays.toString(result));

split a string in java into equal length substrings while maintaining word boundaries

How to split a string into equal parts of maximum character length while maintaining word boundaries?
Say, for example, if I want to split a string "hello world" into equal substrings of maximum 7 characters it should return me
"hello "
and
"world"
But my current implementation returns
"hello w"
and
"orld "
I am using the following code taken from Split string to equal length substrings in Java to split the input string into equal parts
public static List<String> splitEqually(String text, int size) {
// Give the list the right capacity to start with. You could use an array
// instead if you wanted.
List<String> ret = new ArrayList<String>((text.length() + size - 1) / size);
for (int start = 0; start < text.length(); start += size) {
ret.add(text.substring(start, Math.min(text.length(), start + size)));
}
return ret;
}
Will it be possible to maintain word boundaries while splitting the string into substring?
To be more specific I need the string splitting algorithm to take into account the word boundary provided by spaces and not solely rely on character length while splitting the string although that also needs to be taken into account but more like a max range of characters rather than a hardcoded length of characters.
If I understand your problem correctly then this code should do what you need (but it assumes that maxLenght is equal or greater than longest word)
String data = "Hello there, my name is not importnant right now."
+ " I am just simple sentecne used to test few things.";
int maxLenght = 10;
Pattern p = Pattern.compile("\\G\\s*(.{1,"+maxLenght+"})(?=\\s|$)", Pattern.DOTALL);
Matcher m = p.matcher(data);
while (m.find())
System.out.println(m.group(1));
Output:
Hello
there, my
name is
not
importnant
right now.
I am just
simple
sentecne
used to
test few
things.
Short (or not) explanation of "\\G\\s*(.{1,"+maxLenght+"})(?=\\s|$)" regex:
(lets just remember that in Java \ is not only special in regex, but also in String literals, so to use predefined character sets like \d we need to write it as "\\d" because we needed to escape that \ also in string literal)
\G - is anchor representing end of previously founded match, or if there is no match yet (when we just started searching) beginning of string (same as ^ does)
\s* - represents zero or more whitespaces (\s represents whitespace, * "zero-or-more" quantifier)
(.{1,"+maxLenght+"}) - lets split it in more parts (at runtime :maxLenght will hold some numeric value like 10 so regex will see it as .{1,10})
. represents any character (actually by default it may represent any character except line separators like \n or \r, but thanks to Pattern.DOTALL flag it can now represent any character - you may get rid of this method argument if you want to start splitting each sentence separately since its start will be printed in new line anyway)
{1,10} - this is quantifier which lets previously described element appear 1 to 10 times (by default will try to find maximal amout of matching repetitions),
.{1,10} - so based on what we said just now, it simply represents "1 to 10 of any characters"
( ) - parenthesis create groups, structures which allow us to hold specific parts of match (here we added parenthesis after \\s* because we will want to use only part after whitespaces)
(?=\\s|$) - is look-ahead mechanism which will make sure that text matched by .{1,10} will have after it:
space (\\s)
OR (written as |)
end of the string $ after it.
So thanks to .{1,10} we can match up to 10 characters. But with (?=\\s|$) after it we require that last character matched by .{1,10} is not part of unfinished word (there must be space or end of string after it).
Non-regex solution, just in case someone is more comfortable (?) not using regular expressions:
private String justify(String s, int limit) {
StringBuilder justifiedText = new StringBuilder();
StringBuilder justifiedLine = new StringBuilder();
String[] words = s.split(" ");
for (int i = 0; i < words.length; i++) {
justifiedLine.append(words[i]).append(" ");
if (i+1 == words.length || justifiedLine.length() + words[i+1].length() > limit) {
justifiedLine.deleteCharAt(justifiedLine.length() - 1);
justifiedText.append(justifiedLine.toString()).append(System.lineSeparator());
justifiedLine = new StringBuilder();
}
}
return justifiedText.toString();
}
Test:
String text = "Long sentence with spaces, and punctuation too. And supercalifragilisticexpialidocious words. No carriage returns, tho -- since it would seem weird to count the words in a new line as part of the previous paragraph's length.";
System.out.println(justify(text, 15));
Output:
Long sentence
with spaces,
and punctuation
too. And
supercalifragilisticexpialidocious
words. No
carriage
returns, tho --
since it would
seem weird to
count the words
in a new line
as part of the
previous
paragraph's
length.
It takes into account words that are longer than the set limit, so it doesn't skip them (unlike the regex version which just stops processing when it finds supercalifragilisticexpialidosus).
PS: The comment about all input words being expected to be shorter than the set limit, was made after I came up with this solution ;)

Java: Parsing a string based on delimiter

I have to design an interface where it fetches data from machine and then plots it. I have already designed the fetch part and it fetches a string of format A&B#.13409$13400$13400$13386$13418$13427$13406$13383$13406$13412$13419$00000$00000$
First five A&B#. characters are the identifier. Please note that the fifth character is new line feed i.e. ASCII 0xA.
The function I have written -
public static boolean checkStart(String str,String startStr){
String Initials = str.substring(0,5);
System.out.println("Here is start: " + Initials);
if (startStr.equals(Initials))
return true;
else
return false;
}
shows Here is start: A&B#. which is correct.
Question 1:
Why do we need to take str.substring(0,5) i.e. when I use str.substring(0,4) it shows only - Here is start: A&B# i.e. missing new line feed. Why is New Line feed making this difference.
Further to extract remaing string I have to use s.substring(5,s.length()) instead of s.substring(6,s.length())
i.e.
s.substring(6,s.length()) produces 3409$13400$13400$13386$13418$13427$13406$13383$13406$13412$13419$00000$00000$ i.e missing the first char after the identifier A&B#.
Question 2:
My parsing function is:
public static String[] StringParser(String str,String del){
String[] sParsed = str.split(del);
for (int i=0; i<sParsed.length; i++) {
System.out.println(sParsed[i]);
}
return sParsed;
}
It parses correctly for String String s = "A&B#.13409/13400/13400/13386/13418/13427/13406/13383/13406/13412/13419/00000/00000/"; and calling the function as String[] tokens = StringParser(rightChannelString,"/");
But for String such as String s = "A&B#.13409$13400$13400$13386$13418$13427$13406$13383$13406$13412$13419$00000$00000$" , the call String[] tokens = StringParser(rightChannelString,"$"); does not parse the string at all.
I am not able to figure out why this behaviour. Can any one please let me know the solution?
Thanks
Regarding question 1, the java API says that the substring method takes 2 parameters:
beginIndex the begin index, inclusive.
endIndex the end index, exclusive.
So in your example
String: A&B#.134
Index: 01234567
substring(0,4) = indexes 0 to 3 so A&B#, that's why you have to put 5 as the second parameter to recover your line delimiter.
Regarding question 2, I guess that the split method takes a regexp in parameter and $ is a special character. To match the dollar sign I guess you have to escape it with the \ character (as \ is a special char in strings so you must also escape it).
String[] tokens = StringParser(rightChannelString,"\\$");
Q1: review the description of substring in the documentation:
Returns a new string that is a substring of this string.
The substring begins at the specified beginIndex and extends to the
character at index endIndex - 1. Thus the length of the substring
is endIndex-beginIndex.
Q2: the split method takes a regular expression for the separator. $ is a special character for regular expressions, it matches the end of the line.

Categories