Using .length() in Java - java

I have to enter something like John Doe 12345 99 where First name is John, last name is Doe, ID is 12345, and wage is 99. It needs to be all in one string separated by spaces. So I have this:
while(x < Info.length()){
if(Info.charAt(x) == ' '){
First = Info.substring(0,x);
Last = Info.substring(x + 1, Info.length());
IDNum = Integer.parseInt(Info.substring(x + 2, Info.length()));
Wage = Double.parseDouble(Info.substring(x + 3, Info.length()));
x = Info.length();
}
++x;
}
I'm having trouble on the .length(); The example in the book only showed how to break up a string with two words in it. It's the length on IDNum and Wage. I'm not sure where to start them and end them. I think I need to change the ending for the length() when the Last calls it.

If it's separated by a space why not use the split() method:
String info = "John Doe 12345 99";
String[] seperatedInfo = info.split(" ");
String firstName = seperatedInfo[0];
String lastName = seperatedInfo[1];
int ID = Integer.parseInt(seperatedInfo[2]);
double pay = Double.parseDouble(seperatedInfo[3]);
System.out.println(firstName);
System.out.println(lastName);
System.out.println(ID);
System.out.println(pay);
Output:
John
Doe
12345
99
Also side note Java naming conventions for variables is to start with lower case and use camelCase

So, assuming you're not allowed to use something like String#split, which would be my personally preferred method, you could, instead, make use of the indexOf functionality, which supplies a couple of different ways to find the index of the a given character or String within a String.
So, something like...
String text = "John Doe 12345 99";
int index = text.indexOf(" ");
int lastIndex = 0;
while (index > -1) {
String part = text.substring(lastIndex, index);
System.out.println("[" + part + "]");
lastIndex = index + 1;
index = text.indexOf(" ", lastIndex);
}
if (lastIndex != 0) {
String part = text.substring(lastIndex);
System.out.println("[" + part + "]");
}
prints out...
[John]
[Doe]
[12345]
[99]
What I would do, is modify the above to maintain a "counter", which represents the current element you are "extracting" and then add that to the corresponding array element
Caveat: This will work for single "spaces" only, so just beware of that. You could also make use of String#trim to trim of leading and trailing spaces, but would require you to manually disassemble the String (using String#substring)

There are several ways you can parse that String, I would start by spliting it; then assign the tokens as desired. Something like,
String info = "John Doe 12345 99";
String[] tokens = info.split("\\s+");
String first = tokens[0], last = tokens[1];
int id = Integer.parseInt(tokens[2]);
double wage = Double.parseDouble(tokens[3]);
System.out.printf("%d %s, %s %.2f%n", id, last, first, wage);
Which outputs
12345 Doe, John 99.00
Filling tokens without split is still the approach I would take if limited in the methods I can use. You know there are four tokens, and you can use successive calls to indexOf(char) to find spaces. Like,
String info = "John Doe 12345 99";
int p = 0, c = 0;
String[] tokens = new String[4];
while (c < 4) {
int p1 = (c != 3) ? info.indexOf(' ', p) : info.length();
tokens[c] = info.substring(p, p1);
p = p1 + 1;
c++;
}
The rest of the answer above does not need to change.

You can also use StringTokenizer class.
Example:
String str = "John Doe 12345 99";
String delimeter = " ";
StringTokenizer stringTokenizer = new StringTokenizer(str, delimeter);
while (stringTokenizer.hasMoreTokens()) {
System.out.println(stringTokenizer.nextToken());
}

Related

java regex parse

Thanks for checking out my question.
Here the user enter the string in the format: "xD xS xP xH". The program takes the string, splits it on the space bar, then uses regex to parse the string. There is an issue with my "final string regex" and I am not sure where.
final String regex = "([0-9]+)[D|d]| ([0-9]+)[S|s]| ([0-9]+)[P|p]| ([0-9]+)[H|h]";
Lastly, the loop prints out only the value for D so I suspect it reaches an error moving to match S or s.
public class parseStack
{
public parseStack()
{
System.out.print('\u000c');
String CurrencyFormat = "xD xS xP xH";
System.out.println("Please enter currency in the following format: \""+CurrencyFormat+"\" where x is any integer");
Scanner scan = new Scanner(System.in);
String currencyIn = scan.nextLine();
currencyFinal = currencyIn.toUpperCase();
System.out.println("This is the currency you entered: "+currencyFinal);
String[] tokens = currencyFinal.split(" ");
final String input = tokens[0];
final String regex = "([0-9]+)[D|d]| ([0-9]+)[S|s]| ([0-9]+)[P|p]| ([0-9]+)[H|h]";
if (input.matches(regex) == false) {
throw new IllegalArgumentException("Input is malformed.");
}
long[] values = Arrays.stream(input.replaceAll(regex, "$1 $2 $3 $4").split(" "))
.mapToLong(Long::parseLong)
.toArray();
for (int i=0; i<values.length; i++)
{
System.out.println("value of i: "+i+ " |" +values[i]+ "|");
}
//pause to print
System.out.println("Please press enter to continue . . . ");
Scanner itScan = new Scanner(System.in);
String nextIt = itScan.nextLine();
}
}
Your regular expression should be [\d]+[DdSsPpHh].
The problem you are having is you split the string into chunks, then you match chunks with a RegEx that matches the original string that you have split.
HOWEVER this answer only addresses a problem in your code. Your routine doesn't seem to cater your expectation. And your expectation is not clear at all.
EDIT
Added the multidigit requirement.
Your regex can be simplified somewhat.
"(?i)(\d+d) (\d+s) (\d+p) (\d+h)"
will do a case-insensitive match against multiple digits ( \d+ )
This can be further simplified into
"(?i)(\d+[dsph])"
which will iteratively match the various groups in your currency string.
First of all your regex looks a bit to complex. You input format is "xD xS xP xH" also you are converting the input to uppercase currencyIn = currencyIn.toUpperCase(); but this isn't the problem.
The problem is
String[] tokens = currencyIn.split(" ");
final String input = tokens[0];
You are splitting the input and only use the first part which would be "xD"
The fixed code would look like:
String currencyIn = scan.nextLine();
currencyIn = currencyIn.toUpperCase();
System.out.println("This is the currency you entered: "+currencyIn);
final String regex = "([0-9]+)D ([0-9]+)S ([0-9]+)P ([0-9]+)H";
if (!currencyIn.matches(regex)) {
throw new IllegalArgumentException("Input is malformed.");
}
long[] values = Arrays.stream(currencyIn.replaceAll(regex, "$1 $2 $3 $4").split(" "))
.mapToLong(Long::parseLong)
.toArray();
for (int i=0; i<values.length; i++) {
System.out.println("value of i: "+i+ " |" +values[i]+ "|");
}

Find the number of characters till nth word in Java?

What is the easiest way to find the number of characters in a sentence before nth word ?
For eg. :
String sentence = "Mary Jane and Peter Parker are friends."
int trigger = 5; //"Parker"
Output would be
Character count = 20
Any help will be appreciated.
Thanks.
Easiest way would just be to loop around the characters in the String and count the number of white-spaces.
The following increments a length variable for every character. When a white-space is encountered, we decrement the number of remaining white-spaces to read, and when that number reaches 1, it means we hit the wanted word, so we break out of the loop.
public static void main(String[] args) {
String sentence = "Mary Jane and Peter Parker are friends.";
int trigger = 5; //"Parker"
int length = 0;
for (char c : sentence.toCharArray()) {
if (trigger == 1) break;
if (c == ' ') trigger--;
length++;
}
System.out.println(length); // prints 20
}
public int getNumberOfCharacters(int nthWord){
String sentence = "Mary Jane and Peter Parker are friends.";
String[] wordArray = sentence.split(" ");
int count = 0;
for(int i=0; i<=nthWord-2 ; i++){
count = count + wordArray[i].length();
}
return count + (nthWord-1);
}`
try this it should work
Using regex can be done like this:
public static void main(String[] args) {
String sentence = "Mary Jane and Peter Parker are friends.";
int trigger = 5;
Pattern pattern = Pattern.compile(String.format("(?:\\S+\\s+){%d}(\\S+)", trigger - 1));
Matcher matcher = pattern.matcher(sentence);
matcher.find();
System.out.println(matcher.group().lastIndexOf(" ") + 1);
}
I am going through all the trouble of finding the exact work instead of simply indexOf("Parker") because of possible duplicates.
The regex will match N words without capturing and capture the N+1 word. In your case it will match all previous words up to the one you want and capture the next one.

Issues with Java substring method

I wrote a program that prompts a user to input his/her full name First , middle , last. I'm attempting to break that name down into three separate pieces using the substring method by locating each white space in the string. Once each white space is found the following portion of the name is stored in a new string variable.
The issue I'm having is that the middle name is storing both middle and last because the counter isn't stopping correctly as you will see in my below code so my question is how can I fix this.
Please note, I do not want to split the string, I do not want to use a StringTokenizer, I do not want to use Arrays, I already know how to do it that way. All I need to know is how to fix my counter, what I am trying to do will work this way I'm not looking for a new way to do this; I'm only working with substring and charAt.
import java.util.Scanner;
public class Example
{
public static void main(String[] args)
{
String name = "",
firstName = "",
middleName = "",
lastName = "";
Scanner in = new Scanner(System.in);
System.out.print("Please enter your name 'First Middle Last': ");
name = in.nextLine();
int i = 0;
while(i < name.length())
{
if(name.charAt(i) == ' ')
{
firstName = name.substring(0, i); // Starts at 0 ends at first occurence of ' '
/* middleName = name.substring(i + 1, i); Should start at i + 1,
or one postion after the previously located white space and
then end at the next occurence of ' '
^ The above does not work, and this is where the issue is
happening, how ever if I do the following */
middleName = name.substring(i + 1, name.length());
/* This does work but because the endIndex is name.length() it
runs the length of name and grabs both the middle and last name.*/
i = name.length();
}
++i;
}
System.out.print("\nDisplayed with last name first: " + "\nLast Name: " + lastName + "\nFisrt Name: " + firstName + "\nMiddle Name: " + middleName);
}
}
The output this produces looks like this
Please enter your name 'First Middle Last': First Middle Last
Displayed with last name first:
Last Name:
First Name: First
Middle Name: Middle Last
As you can see first Name is displayed correctly.
Middle name is not because it included "Last" and not just "middle"
You could use indexOf(' ') and lastIndexOf(' ') to find first space and last space
everything before 1st space is firstname
everything after last space is lastname
the rest in the middle is middlename
Pseudocode:
firstName = name.substring(0, name.indexOf(' '));
middleName = name.substring(name.indexOf(' ') + 1, name.lastIndexOf(' '));
lastName = name.substring(name.lastIndexOf(' ') + 1);
Instead of substring you can use split function:
String string = "Peter Ralph Joseph"; //Here the string
String[] parts = string.split(" "); //Here the string it is divide taking as reference the space
System.out.println(parts[0]); //Peter
System.out.println(parts[1]); //Ralph
System.out.println(parts[2]); //Joseph
In my opinion, it is easier and faster to do it with split function.
Instead of running through a loop with charAt, if you really want to use substring you could just do:
int firstSpace = fullName.indexOf(' ');
String firstName = fullName.substring(0, firstSpace);
int secondSpace = fullName.indexOf(' ', firstSpace+1);
String middleName = fullName.substring(firstSpace+1, secondSpace);
String lastName = fullName.substring(secondSpace+1);
var mode = 0;
var last = 0;
for(i=0;i<name.length();i++)
{
if(name.charAt(i)==' '||i==(name.length()-1))
{
mode++;
var text = name.substring(last, i-last);
last = i+1;
if(mode==1) { firstName = text; }
else if(mode==2) { middleName = text; }
else if(mode==3) { lastName = text; break; }
}
}
do it in the following way:
no need to run the while loop.
firstName=name.substring(0,name.indexOf(' '));
middleName=name.substring(name.indexOf(' ')+1,name.lastIndexOf(' '));
lastName=name.substring(name.lastIndexOf(' ')+1,name.length());

Seeing if a index is negaitve

I am writing a program for my structured programming class and we have to take a input string, break it into 3 substrings and then check to see if all three names are there. I have the string broken up at the spaces and now I just need to check that there are three spaces. My professor told us that we had to make sure that there is a space between each name. He told me to simply test if the index of the space character is -1, because if it is the space wont be there. I just cant find a way to test it without getting a "string index out of range" error. Any help would be much appreciated. This is the code I am using to test the input string.
System.out.println("Enter filer full name (First Middle Last):");
Scanner input = new Scanner(System.in);
String fullName = input.nextLine();
int n = fullName.indexOf(' ');
int m = fullName.indexOf(' ', n + 1);
String firstName = fullName.substring(0, n);
String middleName = fullName.substring(n + 1, m);
String lastName = fullName.substring(m + 1);
Before you take the substrings, useif(n >-1 && m > -1) to tell if you have the spaces. Your new code would look something like this
System.out.println("Enter filer full name (First Middle Last):");
Scanner input = new Scanner(System.in);
String fullName = input.nextLine();
int n = fullName.indexOf(' ');
int m = fullName.indexOf(' ', n + 1);
if(n>-1&&m>-1){
String firstName = fullName.substring(0, n);
String middleName = fullName.substring(n + 1, m);
String lastName = fullName.substring(m + 1);
}else{
System.out.println("Don't have spaces!");
}
indexOf returns negative one if the input is not contained in the String. Also, String indices start at zero. So to test for it you would do something like this:
if (fullName.indexOf(" ") == -1)
{
System.out.print("Space not contained in fullName");
} //end if
How about just using a split
String fullname = "Scary Old Wombat";
String [] names = fullname.split (" ");
assert (names.length == 3);
You can use the indexOf() method for this.
Eg:
if(fullName.indexOf(' ') == -1){
// index of space is -1, means space is not present
}
Some names may or may not have a middle name as in John Doe while some names may have a middle name that comprises of more than 2 names as in John Smith Williams Joseph Doe.
Hence you can try this!
System.out.println("Enter filer full name (First Middle Last):");
Scanner input = new Scanner(System.in);
String fullName = input.nextLine();
String name [] = fullName.split(" ");
if(name.length == 1) {
System.out.println("You don't have spaces in the name");
}
else
if(name.length == 2) {
System.out.println("First Name: " + name[0]);
System.out.println("Last Name: " + name[1]);
}else
if(name.length > 2) {
System.out.println("First Name: " + name[0]);
System.out.print("Middle Name: ");
for (int i = 1; i < (name.length-1) ; i++) {
System.out.print(name[i] + " ");
}
System.out.println();
System.out.println("Last Name: " + name[(name.length-1)]);
}
Output - Enter filer full name (First Middle Last):
John Smith Williams Joseph Doe
First Name: John
Middle Name: Smith Williams Joseph
Last Name: Doe

Extract number from a String

i have a large String which includes numbers and text.
Now i want exactly a number from that string.
The number starts every time with a '6' and three '0' but then the number can be different digits.
For example here is a try:
String text1 = "ID 6 IDENTIFICATION NUMBER 600026821 NAME: BECK POSTCODE 60025";
if(text1.contains("6000"))
{
System.out.println(text1.indexOf("6000"));
}
So as you can see the String can also contains postcode digits and ids.
But the number i want has always the same length of 9 digits and starts with '6000...'.
So how can i extract that number?
Thanks
EDIT
Ok now i try this one:
String index = "6000";
String text1 = "ID 6 IDENTIFICATION NUMBER 600026821 NAME BECK POSTCODE 60025";
System.out.println(text1.indexOf(index));
String number = text1.substring(text1.indexOf(index), text1.lastIndexOf(text1.indexOf(index) + 5));
System.out.println(number);
It starts but ends not correctly
Regex can be used like this :
public static void main(String args[]) {
String text1 = "ID 6 IDENTIFICATION NUMBER 600026821 NAME: BECK POSTCODE 60025";
System.out.println(text1.replaceAll(".*?\\b(6000\\d+)\\b.*", "$1")); // replace everything except a number that starts with 6 and is followed by 000 with "".
}
O/P :
600026821
Note : You can use (6000\\d{5}) instead of (6000\\d+) if you are certain that the number of digits will be 9.
for (String word : s.split(" ")) {
int number = 0;
if (word.startsWith("6000"))
number = Integer.parseInt(word);
}
}
EDIT
I hadn't read that the number you wanted is always of length 9. In that case, check its length in the if condition:
if (word.startsWith("6000") && word.length() == 9)
Like that:
System.out.println(text1.substring(text1.indexOf("6000"),text1 .indexOf("6000")+9));
int value=Integer.parseInt(text1.substring(text1.indexOf("6000"),text1 .indexOf("6000")+9));
Once you have the index of the "6000" just continue, you already said that the length is always 9
int start = text1.indexOf("6000");
String yourNumber = text1.substring(start, start+10);
You can do it like this to get all numbers in that string that follow your rules. Note that I added some more numbers to text1 for testing purposes.
package so;
public class NumberExtractor {
public static void main(String[] args) {
String text1 = "ID 6 IDENTIFICATION NUMBER 600026821 NAME: BECK 600026822600026823 POSTCODE 60002682460025";
boolean notAtTheEnd = true;
int currentIndex = 0;
while (notAtTheEnd) {
int start = text1.indexOf("6000", currentIndex);
if (start > -1) {
String number = text1.substring(start, start + 9);
currentIndex = start + 1;
System.out.println(number);
} else {
notAtTheEnd = false;
}
}
}
}

Categories

Resources