Using the second StringTokenizer constructor, write a method that
returns either the first or second token in the input string based on
the token argument. You will need to set custom delimiters which are
enclosed in a string but not separated by commas.
okay, so this is what i have so far..... i need help making the code so that it returns either the first or the second token depending on the users input.... right now i only know how to return either the first or the second token. ive tried making a while or and if statement but it always says i cant convert int to string, ive even tried type casting but it wouldnt let me do that either.... what can i do to make it return whichever token the user inputs?
String parseEqn_p2(String input, int token) {
StringTokenizer st = new StringTokenizer(input, "+-/*%");
String first = st.nextToken();
String second = st.nextToken();
return first ;
""it always says i cant convert int to string," - Use String.valueOf(int)
You probably want something like this
if (first.eqauls(String.valueOf(token)) {
return first;
} else if (...) {
}
return null; // if not found
...
Note : you may also need to .trim() the token, depending on what the input is. If there are spaces, the tokenizer won't exclude them, so you would need to call .trim() on the String first before trying to compare. like
String first = st.nextToken().trim();
Also, it looks like you may want to use a character class, because what you're doing is looking using a single delimiter of all the characters, which isn't what you want. Try this instead
StringTokenizer st = new StringTokenizer(input, "[+-/*%]");
In for any case you wanted the method to return an int, then you would need to parse the token
int first = Integer.parseInt(st.nextToken());
Also, NOTE: Whoever gave you this assignment, ask them to read the documentation for StringTokenizer, where you'll find this excerpt
StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.
The following example illustrates how the String.split method can be used to break up a string into its basic tokens:
String[] result = "this is a test".split("\\s");
for (int x=0; x<result.length; x++)
System.out.println(result[x]);
Related
I have a string which is :
1|name|lastname|email|tel \n
2|name|lastname|email|tel \n
I know that I have to use a loop to display all lines but the problem is that in my assignment
I can't use arrays or other classes than String and System.
Also I would like to sort names by ascending order without using sort method or arrays.
Do I have to use compareTo method to compare two names ?
If that's the case, how do I use compareTo method to sort names.
For example, if compareTo returns 1, that means that the name is greater than the other one. In that case how do I manage the return to sort name properly in the string ?
To display all substrings of the string as in the example, you can just go through all characters one by one and store them in a string. Whenever you hit a delimiter (e.g. | or \n), print the last string.
Here's a thread on iterating through characters of a string in Java:
What is the easiest/best/most correct way to iterate through the characters of a string in Java?
If you also need to sort the names in ascending order without an array, you will need to scan the input many times - sorting N strings takes at least N*log(N) steps. If this is a data structure question, PriorityQueue should do the trick for you - insert all substrings and then pop them out in a sorted fashion :)
building on the previous answer by StoneyKeys, since i do not have the privilege to comment, you can use a simple if statement that when the char is a delimiter, System.out.println() your previous scanned string. Then you can reset the string to an empty string in preparation for scanning the next string.
In java, there are special .equals() operators for strings and chars so when you won't be using == to check strings or char. Do look into that. To reset the value of string just assign it a new value. This is because the original variable points at a certain string ie "YHStan", by making it point at "", we are effectively "resetting" the string. ie scannedstr = "";
Please read the code and understand what each line of code does. The sample code and comments is only for your understanding, not a complete solution.
String str ="";
String value = "YH\nStan";
for (int i=0; i <value.length(); i++) {
char c = value.charAt(i);
String strc = Character.toString(c);
//check if its a delimiter, using a string or char .equals(), if it is print it out and reset the string
if (strc.equals("\n")) {
System.out.println(str);
str ="";
continue; // go to next iteration (you can instead use a else if to replace this)
}
//if its not delimiter append to str
str = str +strc;
//this is to show you how the str is changing as we go through the loop.
System.out.println(str);
}
System.out.println(str); //print out final string result
This gives a result of:
Y
YH
YH
S
St
Sta
Stan
Stan
I have this code:
StringTokenizer st = new StringTokenizer (line, String.valueOf(delimiter));
labels.add("Time");
int currentCol = 1;
while (st.hasMoreTokens())
{
st.nextToken();
labels.add(new String("c" + currentCol++));
}
Where delimiter is ; and line is 0.6245.
Why do I end up with an ArrayList labels that has it's second element c1? While the documentation says:
Tests if there are more tokens available from this tokenizer's string. If this method returns true, then a subsequent call to nextToken with no argument will successfully return a token.
Returns:
true if and only if there is at least one token in the string after the current position; false otherwise.
Since value: 0.6245 cannot be split by delimiter ; why would hasMoreTokens() return true?
EDIT:
Now I understand why while loop get's to execute at least once. It is because that is the way StringTokenizer works. Rather than regular split that I am used to where I can access any position of the resulting array, here the only way to access elements is with the nextElement() method. Which means that even if there is only one element in the StringTokenizer it will always return true from hasMoreTokens().
The reason why I am wondering about StringTokenizer which is what I learned a legacy class is that I am reviewing an old code that I am about to reuse.
Your problem is because you are adding an element on your list outside your loop:
labels.add("Time");
You have just one token after the Tokenize works. That's because when you tokenize a String that hasn't the informed delimiter you have only one element, so if your string is 0.6245 understand it as tokens as (for your delimiter):
First token: 0.6245
Second token: nothing
It is like if it was: 0.6245;
Inside your loop you are adding another thing to your array list:
labels.add(new String("c" + currentCol++));
Since you initialized currentCol as 1 and the while will run just once it will have the c1 as value on the second element of your list (remember, you have added one before)
I don't know what are you trying to achieve. But it seems like you want something like:
StringTokenizer st = new StringTokenizer (line, String.valueOf(delimiter));
//Don't add this:
//labels.add("Time");
int currentCol = 1;
while (st.hasMoreTokens())
{
String someThing = st.nextToken();
labels.add(new String("Current token:" + someThing
+ "\n currentCol: " + currentCol++));
}
0.6245 is itself a token though you don't have a delimiter.
If you would have something like this "0.6245;0.987" then it has 2 tokens. Unless your line has an empty space or a null value while loop will be entered at least once.
Obviously, for an IRC bot, input is generated by a user typing a single string, usually with a command and a few arguments, each separated by a space. I am coding an IRC bot using Java and would like to parse arguments that might vary in character length and save them into multiple strings for use later. I would like to make a command that looks something like this:
bot.command argument1 argument2 argument3
and I want it to be so that if the message starts with bot.command, then user will store argument1, time will store argument2, and date will store argument3. The thing is, though, that argument1, argument2, and argument3 could vary in character length, so doing something like time = message.substring(33, message.length()) will stop reading at the end of the argument, but it won't always read the string where the argument3's text begins. I need to detect where the separator space is and start reading argument3 from one character after that. And I can't use If statements to determine what the arguments might be, because they could be anything. Here's a template, if the above paragraph isn't clear:
String message //= the IRC message and bot input
String user;
String time;
String date;
if (message.startsWith("bot.command")) {
user = message.substring(13, detect next space here and stop reading one character before);
time = message.substring(detect where previous space was and start one character after that, end before next space);
date = message.substring(detect where previous space was and start one character after that, message.length());
}
I hope that kind of illustrates what I'm trying to do. Thank you for your help!
I'd recommend using String.split, which breaks up a string into an array using a delimiter regular expression. In your case, you might do:
String[] args = message.split("\\s+");
if (args[0].equals("bot.command"))
{
user = args[1];
...
}
The reason I'm splitting on the pattern \s+ (matches one or more whitespace characters) instead of just a space is that this way the program won't crash if the arguments are separate by more than one space or by something like a tab.
Edit (Removed StringTokenizer example) -
Since StringTokenizer is apparently "legacy", I would use a Scanner like this -
String message = "BOT.command USER_X THIS_IS_A_TIME THIS_IS_A_DATE";
String user = null;
String time = null;
String date = null;
// Use toLowerCase - assuming it's case insensitive.
if (message.toLowerCase()
.startsWith("bot.command")) {
Scanner st = new Scanner(message);
if (st.hasNext()) {
st.next();
}
if (st.hasNext()) {
user = st.next();
}
if (st.hasNext()) {
time = st.next();
}
if (st.hasNext()) {
date = st.next();
}
}
System.out.printf(
"User = %s, Time = %s, Date = %s\n", user,
time, date);
Output is
User = USER_X, Time = THIS_IS_A_TIME, Date = THIS_IS_A_DATE
If you are taking user input where you are not sure about how many space separated input words will be entered, you can do the following:
String[] terms = message.split("\\s+");
for(String word1 : terms) {
// doSomething()
}
But in your case, you just need 3 arguments, hence the looping will be done 3 times in the for loop.
I'm moving some code from objective-c to java. The project is an XML/HTML Parser. In objective c I pretty much only use the scanUpToString("mystring"); method.
I looked at the Java Scanner class, but it breaks everything into tokens. I don't want that. I just want to be able to scan up to occurrences of substrings and keep track of the scanners current location in the overall string.
Any help would be great thanks!
EDIT
to be more specific. I don't want Scanner to tokenize.
String test = "<title balh> blah <title> blah>";
Scanner feedScanner = new Scanner(test);
String title = "<title";
String a = feedScanner.next(title);
String b = feedScanner.next(title);
In the above code I'd like feedScanner.next(title); to scan up to the end of the next occurrence of "<title"
What actually happens is the first time feeScanner.next is called it works since the default delimiter is whitespace, however, the second time it is called it fails (for my purposes).
You can achieve this with String class (Java.lang.String).
First get the first index of your substring.
int first_occurence= string.indexOf(substring);
Then iterate over entire string and get the next value of substrings
int next_index=indexOf( str,fromIndex);
If you want to save the values, add them to the wrapper class and the add to a arraylist object.
This really is easier by just using String's methodsdirectly:
String test = "<title balh> blah <title> blah>";
String target = "<title";
int index = 0;
index = test.indexOf( target, index ) + target.length();
// Index is now 6 (the space b/w "<title" and "blah"
index = test.indexOf( target, index ) + target.length();
// Index is now at the ">" in "<title> blah"
Depending on what you want to actually do besides walk through the string, different approaches might be better/worse. E.g. if you want to get the blah> blah string between the <title's, a Scanner is convenient:
String test = "<title balh> blah <title> blah>";
Scanner scan = new Scanner(test);
scan.useDelimiter("<title");
String stuff = scan.next(); // gets " blah> blah ";
Maybe String.split is something for you?
s = "The almighty String is mystring is your String is our mystring-object - isn't it?";
parts = s.split ("mystring");
Result:
Array("The almighty String is ", " is your String is our ", -object - isn't it?)
You know that in between your "mystring" must be. I'm not sure for start and end, so maybe you need some s.startsWith ("mystring") / s.endsWith.
I am reading in a csv file in Java and, depending on the format of the string on a given line, I have to do something different with it. The three different formats contained in the csv file are (using random numbers):
833
"79, 869"
"56-57, 568"
If it is just a single number (833), I want to add it to my ArrayList. If it is two numbers separated by a comma and surrounded by quotations ("79, 869)", I want to parse out the first of the two numbers (79) and add it to the ArrayList. If it is three numbers surrounded by quotations (where the first two numbers are separated by a dash, and the third by a comma ["56-57, 568"], then I want to parse out the third number (568) and add it to the ArrayList.
I am having trouble using str.contains() to determine if the string on a given line contains a dash or not. Can anyone offer me some help? Here is what I have so far:
private static void getFile(String filePath) throws java.io.IOException {
BufferedReader reader = new BufferedReader(new FileReader(filePath));
String str;
while ((str = reader.readLine()) != null) {
if(str.endsWith("\"")){
if (str.contains(charDash)){
System.out.println(str);
}
}
}
}
Thanks!
I recommend using the version of indexOf that actually takes a char rather than a string, since this method is much faster. (It is a simple loop, without a nested loop.)
I.e.
if (str.indexOf('-')!=-1) {
System.out.println(str);
}
(Note the single quotes, so this is a char, rather than a string.)
But then you have to split the line and parse the individual values. At present, you are testing if the whole line ends with a quote, which is probably not what you want.
The following code works for me (note: I wrote it with no optimization in mind - it's just for testing purposes):
public static void main(String args[]) {
ArrayList<String> numbers = GetNumbers();
}
private static ArrayList<String> GetNumbers() {
String str1 = "833";
String str2 = "79, 869";
String str3 = "56-57, 568";
ArrayList<String> lines = new ArrayList<String>();
lines.add(str1);
lines.add(str2);
lines.add(str3);
ArrayList<String> numbers = new ArrayList<String>();
for (Iterator<String> s = lines.iterator(); s.hasNext();) {
String thisString = s.next();
if (thisString.contains("-")) {
numbers.add(thisString.substring(thisString.indexOf(",") + 2));
} else if (thisString.contains(",")) {
numbers.add(thisString.substring(0, thisString.indexOf(",")));
} else {
numbers.add(thisString);
}
}
return numbers;
}
Output:
833
79
568
Although it gets a lot of hate these days, I still really like the StringTokenizer for this kind of stuff. You can set it up to return the tokens and, at least to me, it makes the processing trivial without interacting with regexes
you'd have to create it using ",- as your tokens, then just kick it off in a loop.
st=new StringTokenizer(line, "\",-", true);
Then you set up a loop:
while(st.hasNextToken()) {
String token=st.nextToken();
Each case becomes it's own little part of the loop:
// Use punctuation to set flags that tell you how to interpret the numbers.
if(token == "\"") {
isQuoted = !isQuoted;
} else if(token == ",") {
...
} else if(...) {
...
} else { // The punctuation has been dealt with, must be a number group
// Apply flags to determine how to parse this number.
}
I realize that StringTokenizer is outdated now, but I'm not really sure why. Parsing regular expressions can't be faster and the syntax is--well split is a pretty sweet syntax I gotta admit.
I guess if you and everyone you work with is really comfortable with Regular Expressions you could replace that with split and just iterate over the resultant array but I'm not sure how to get split to return the punctuation--probably that "+" thing from other answers but I never trust that some character I'm passing to a regular expression won't do something utterly unexpected.
will
if (str.indexOf(charDash.toString()) > -1){
System.out.println(str);
}
do the trick?
which by the way is fastest than contains... because it implements indexOf
Will this work?
if(str.contains("-")) {
System.out.println(str);
}
I wonder if the charDash variable is not what you are expecting it to be.
I think three regexes would be your best bet - because with a match, you also get the bit you're interested in. I suck at regex, but something along the lines of:
.*\-.*, (.+)
.*, (.+)
and
(.+)
ought to do the trick (in order, because the final pattern matches anything including the first two).