I have a file for example like this :
file.txt
Milano Tirana Paris
Madrid Istanbul Berlin
And I want to read just the third words of each line Paris and Berlin. I tried with substring but it won't work because the length changes. How can I do it ?
I'd recommend reading the whole line, tokenizing it by splitting it at whitespace, and return the index of the value you want.
Something like this:
package misc;
/**
* CityParser demo
* #author Michael
* #link https://stackoverflow.com/questions/24420434/read-the-third-string-only-java/24420447#24420447
* #since 6/25/2014 8:36 PM
*/
public class CityParser {
public static void main(String[] args) {
int tokenIndex = 2;
CityParser parser = new CityParser();
for (String arg : args) {
System.out.println((String.format("line: '%s' tokenIndex: %d token: %s", args, tokenIndex, parser.getToken(arg, tokenIndex))));
}
}
public String getToken(String line, int tokenIndex) {
String token = null;
if ((line != null) && (line.trim().length() > 0)) {
String [] tokens = line.split("\\s+");
if ((tokens.length > 0)) {
token = tokens[tokenIndex];
}
}
return token;
}
}
You can search for the character " ". So for every line, count two " "'s then record kbd.next() to get the word.
Related
in my homework I need to extract the server name from the url
at the same time, I need to take into account that there may not be a slash after the server name
I'm not allowed to use a loop
At the same time, I am once again trying to redo a remark from my teacher:
"Now substring can be done twice (if it goes into if). You need to make sure that only one substring is made for any variant of the function execution"
how can this be fixed? I've tried everything
public class Url {
public static String getServerName(String url) {
int index1 = url.indexOf("://") + 3;
String serverName = url.substring(index1);
int index2 = serverName.indexOf("/");
if (index2 >= 0) {
return url.substring(index1, index1 + index2);
}
return serverName;
}
public static void main(String[] args) {
String url = "https://SomeServerName";
System.out.println(getServerName(url));
}
}
Using Antlr 4 I have a situation I am not sure how to resolve. I originally asked the question at https://groups.google.com/forum/#!topic/antlr-discussion/1yxxxAvU678 on the Antlr discussion forum. But that forum does not seem to get a lot of traffic, so I am asking again here.
I have the following grammar:
expression
: ...
| path
;
path
: ...
| dotIdentifierSequence
;
dotIdentifierSequence
: identifier (DOT identifier)*
;
The concern here is that dotIdentifierSequence can mean a number of things semantically, and not all of them are "paths". But at the moment they are all recognized as paths in the parse tree and then I need to handle them specially in my visitor.
But what I'd really like is a way to express the dotIdentifierSequence usages that are not paths into the expression rule rather than in the path rule, and still have dotIdentifierSequence in path to handle path usages.
To be clear, a dotIdentifierSequence might be any of the following:
A path - this is a SQL-like grammar and a path expression would be like a table or column reference in SQL, e.g. a.b.c
A Java class name - e.g. com.acme.SomeJavaType
A static Java field reference - e.g. com.acme.SomeJavaType.SOME_FIELD
A Java enum value reference - e.g. com.acme.Gender.MALE
The idea is that during visitation "dotIdentifierSequence as a path" resolves as a very different type from the other usages.
Any idea how I can do this?
The issue here is that you're trying to make a distinction between "paths" while being created in the parser. Constructing paths inside the lexer would be easier (pseudo code follows):
grammar T;
tokens {
JAVA_TYPE_PATH,
JAVA_FIELD_PATH
}
// parser rules
PATH
: IDENTIFIER ('.' IDENTIFIER)*
{
String s = getText();
if (s is a Java class) {
setType(JAVA_TYPE_PATH);
} else if (s is a Java field) {
setType(JAVA_FIELD_PATH);
}
}
;
fragment IDENTIFIER : [a-zA-Z_] [a-zA-Z_0-9]*;
and then in the parser you would do:
expression
: JAVA_TYPE_PATH #javaTypeExpression
| JAVA_FIELD_PATH #javaFieldExpression
| PATH #pathExpression
;
But then, of course, input like this java./*comment*/lang.String would be tokenized wrongly.
Handling it all in the parser would mean manually looking ahead in the token stream and checking if either a Java type, or field exists.
A quick demo:
grammar T;
#parser::members {
String getPathAhead() {
Token token = _input.LT(1);
if (token.getType() != IDENTIFIER) {
return null;
}
StringBuilder builder = new StringBuilder(token.getText());
// Try to collect ('.' IDENTIFIER)*
for (int stepsAhead = 2; ; stepsAhead += 2) {
Token expectedDot = _input.LT(stepsAhead);
Token expectedIdentifier = _input.LT(stepsAhead + 1);
if (expectedDot.getType() != DOT || expectedIdentifier.getType() != IDENTIFIER) {
break;
}
builder.append('.').append(expectedIdentifier.getText());
}
return builder.toString();
}
boolean javaTypeAhead() {
String path = getPathAhead();
if (path == null) {
return false;
}
try {
return Class.forName(path) != null;
} catch (Exception e) {
return false;
}
}
boolean javaFieldAhead() {
String path = getPathAhead();
if (path == null || !path.contains(".")) {
return false;
}
int lastDot = path.lastIndexOf('.');
String typeName = path.substring(0, lastDot);
String fieldName = path.substring(lastDot + 1);
try {
Class<?> clazz = Class.forName(typeName);
return clazz.getField(fieldName) != null;
} catch (Exception e) {
return false;
}
}
}
expression
: {javaTypeAhead()}? path #javaTypeExpression
| {javaFieldAhead()}? path #javaFieldExpression
| path #pathExpression
;
path
: dotIdentifierSequence
;
dotIdentifierSequence
: IDENTIFIER (DOT IDENTIFIER)*
;
IDENTIFIER
: [a-zA-Z_] [a-zA-Z_0-9]*
;
DOT
: '.'
;
which can be tested with the following class:
package tl.antlr4;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
public class Main {
public static void main(String[] args) {
String[] tests = {
"mu",
"tl.antlr4.The",
"java.lang.String",
"foo.bar.Baz",
"tl.antlr4.The.answer",
"tl.antlr4.The.ANSWER"
};
for (String test : tests) {
TLexer lexer = new TLexer(new ANTLRInputStream(test));
TParser parser = new TParser(new CommonTokenStream(lexer));
ParseTreeWalker.DEFAULT.walk(new TestListener(), parser.expression());
}
}
}
class TestListener extends TBaseListener {
#Override
public void enterJavaTypeExpression(#NotNull TParser.JavaTypeExpressionContext ctx) {
System.out.println("JavaTypeExpression -> " + ctx.getText());
}
#Override
public void enterJavaFieldExpression(#NotNull TParser.JavaFieldExpressionContext ctx) {
System.out.println("JavaFieldExpression -> " + ctx.getText());
}
#Override
public void enterPathExpression(#NotNull TParser.PathExpressionContext ctx) {
System.out.println("PathExpression -> " + ctx.getText());
}
}
class The {
public static final int ANSWER = 42;
}
which would print the following to the console:
PathExpression -> mu
JavaTypeExpression -> tl.antlr4.The
JavaTypeExpression -> java.lang.String
PathExpression -> foo.bar.Baz
PathExpression -> tl.antlr4.The.answer
JavaFieldExpression -> tl.antlr4.The.ANSWER
I want to generate string of given length, from given characters. The order of the characters matters, also I want to use multiple threads to generate it. Here are a few examples:
chars: a,b,c,d
length: 1
output:
a
b
c
d
chars: a,b,c,d
length: 2
output:
aa
ab
ac
ad
bb
ba
bc
bd
cc
ca
cb
cd
dd
da
db
dc
I've tried this algorithm:
Note: it's pseudo-code
func generate(set, str, k){
if (k == 0){
print str;
return;
}
for (c in set) {
newString = str + c;
generate(set, newString, k-1);
}
}
However I don't see how to use multiple threads. All other algorithms I've read about don't suite my needs.
No need of use multithreading for this algorithm. The for loop is only for generating string for required length. In java the code is like this.
import java.util.Random;
public class RandomString2 {
static String[] option = {"a","b","v","k"};
static String getRandomElement()
{
int idx = new Random().nextInt(option.length);
return option[idx];
}
static String getRandomString(int length)
{
String result="";
for(int i = 1; i<=length ; i++)
{
result += getRandomElement();
}
return result;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(getRandomString(5)); // pass string length as parameter
}
}
Lab Description : Compare two strings to see if each of the two strings contains the same letters in the
same order.
This is what I have so far far:
import static java.lang.System.*;
public class StringEquality
{
private String wordOne, wordTwo;
public StringEquality()
{
}
public StringEquality(String one, String two)
{
setWords (wordOne, wordTwo);
}
public void setWords(String one, String two)
{
wordOne = one;
wordTwo = two;
}
public boolean checkEquality()
{
if (wordOne == wordTwo)
return true;
else
return false;
}
public String toString()
{
String output = "";
if (checkEquality())
output += wordOne + " does not have the same letters as " + wordTwo;
else
output += wordOne + " does have the same letters as " + wordTwo;
return output;
}
}
My runner looks like this:
import static java.lang.System.*;
public class StringEqualityRunner
{
public static void main(String args[])
{
StringEquality test = new StringEquality();
test.setWords(hello, goodbye);
out.println(test);
}
}
Everything is compiling except for the runner. It keeps saying that hello and goodbye aren't variables. How can I fix this so that the program does not read hello and goodbye as variables, but as Strings?
You need to quote strings otherwise they are treated as variables.
"hello"
"goodbye"
so this would work better.
test.setWords("hello", "goodbye");
Problem with your code is with checkEquality(), you are comparing the string's position in memory when you use == use .equals() to check the string
public boolean checkEquality()
{
if (wordOne == wordTwo) //use wordOne.equals(wordTwo) here
return true;
else
return false;
}
Enclose them in double-quotes.
I want to get the highest available string value in java how can i achieve this.
Example: hello jameswangfron
I want to get the highest string "jameswangfron"
String Text = request.getParameter("hello jameswangfron");
Please code example.
public class HelloWorld{
public static void main(String []args){
String text = "hello jameswangfron";
String[] textArray = text.split(" ");
String biggestString = "";
for(int i=0; i<textArray.length; i++){
if(i==0) {
textArray[i].length();
biggestString = textArray[i];
} else {
if(textArray[i].length()>textArray[i-1].length()){
biggestString = textArray[i];
}
}
}
System.out.println("Biggest String : "+biggestString);
}
}
And it shows the output as
Biggest String : jameswangfron
Maybe this will be easyer to understand
public class HelloWorld {
public static void main(String[] args) {
System.out.println(StringManipulator.getMaxLengthString("hello jameswangfron", " "));
}
}
class StringManipulator{
public static String getMaxLengthString(String data, String separator){
String[] stringArray = data.split(separator);
String toReturn = "";
int maxLengthSoFar = 0;
for (String string : stringArray) {
if(string.length()>maxLengthSoFar){
maxLengthSoFar = string.length();
toReturn = string;
}
}
return toReturn;
}
}
But there is a catch. If you pay attention to split method from class String, you will find out that the spliter is actually a regex. For your code, i see that you want to separate the words (which means blank space). if you want an entire text to search, you have to pass a regex.
Here's a tip. If you want your words to be separated by " ", ".", "," (you get the ideea) then you should replace the " " from getMaxLengthString method with the following
"[^a-zA-Z0-9]"
If you want digits to split up words, simply put
"[^a-zA-Z]"
This tells us that we use the separators as anything that is NOT a lower case letter or upper case letter. (the ^ character means you don't want the characters you listed in your brackets [])
Here is another way of doing this
"[^\\w]"
\w it actually means word characters. so if you negate this (with ^) you should be fine