How To Parse a URL in J2ME - java

I'm trying to extract the query's name-value pairs from a URL using J2ME, but it doesn't make it easy. J2ME doesn't have the java.net.URL class nor does String have a split method.
Is there a way to extract name-value pairs from a URL using J2ME? Any open source implementations would be welcome too.

I like kchau answer but i just changed the data structure from two arrays to one Hashtable. This will also help if the number of URL parameters is unknown.
String url = "http://www.so.com?name1=value1&name2=value2&name3=value3";
Hashtable values = new Hashtable();
int s = url.indexOf("?");
int e = 0;
while (s != -1) {
e = url.indexOf("=", s);
String name = url.substring(s + 1, e);
s = e + 1;
e = url.indexOf("&", s);
if (e < 0) {
values.put(name, url.substring(s, url.length()));
} else {
values.put(name, url.substring(s, e));
}
s = e;
}
for (Enumeration num = values.keys(); num.hasMoreElements();) {
String key = (String)num.nextElement();
System.out.println(key + " " + values.get(key));
}

Here's my stab at it, some similarity to David's answer.
String url = "http://www.stackoverflow.com?name1=value1&name2=value2&name3=value3";
String[] names = new String[10];
String[] values = new String[10];
int s = url.indexOf("?"); // Get start index of first name
int e = 0, idx = 0;
while (s != -1) {
e = url.indexOf("=", s); // Get end index of name string
names[idx] = url.substring(s+1, e);
s = e + 1; // Get start index of value string
e = url.indexOf("&", s); // Get index of next pair
if (e < 0) // Last pair
values[idx] = url.substring(s, url.length());
else // o.w. keep storing
values[idx] = url.substring(s, e);
s = e;
idx++;
}
for(int x = 0; x < 10; x++)
System.out.println(names[x] +" = "+ values[x]);
Tested it, and I think it works. Hope it helps, good luck.

Since the Java JDK is open-source, you could also borrow the java URL class from the main JDK and add it to your project. This would let you use the same implementation from Java SE:
http://www.docjar.com/html/api/java/net/URL.java.html

Off the top of my head, it'd go something like this (warning: untested):
String url = ...;
int s = url.indexOf("?") + 1;
while (s > 0) {
int e = url.indexOf("=", s);
String name = url.substring(s, e), value;
s = e + 1;
e = url.indexOf("&", s);
if (e < 0)
value = url.substring(s, e);
else
value = url.substring(s, e);
// process name, value
s = e;
}
Query strings can technically be separated by a semicolon instead of an ampersand, like name1=value1;name2=value2;..., although I've never seen it done in practice. If that's a concern for you, I'm sure you can fix up the code for it.

There's a J2ME implementation that doesn't have java.net.URL?
It's part of the Connected Device Configuration, Foundation Profile, Personal Basis Profile, and Personal Profile...
Edit: For the record, these are the CDC 1.1.2 links, but according to JSR36, CDC 1.0 also has a java.net.URL class.

Also, please note, that url params are URL-Encoded, so you may need to decode them first (how to do it is another question)
I get parameters in this way:
public String getUrlParam(String url, String param)
{
int startIndex = url.indexOf(""+param+"=");
if (startIndex == -1)
return null;
int length = (""+param+"=").length();
int endIndex = url.indexOf("&", startIndex+length);
if (endIndex == -1)
endIndex = url.length();
return URLDecode(url.substring(startIndex+length, endIndex));
}

A URL Encoder/Decoder is really simple and easy to write. You can also look up any open source HTML to WML transcoder code on the internet and modify it. Shouldnt be too hard.

Related

Applying Linear and Binary Searches to Arrays

I have to create a program that takes a user input (a number) and then the program should have that number and apply a search to the array and output the corresponding title by matching the index and the number the user inputted. However during run time, nothing happens. I have set breakers in my code and noticed a problem with the for loop (search algorithm). Please help me and let me know what is wrong is my search algorithm. What I am trying to do is use the number of that the user inputs to match a index and then output the book title that is stored in the index.
private void btnFindActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
// declares an array
String[] listOfBooks = new String [101];
// assigns index in array to book title
listOfBooks[1] = "The Adventures of Tom Sawyer";
listOfBooks[2] = "Huckleberry Finn";
listOfBooks[4] = "The Sword in the Stone";
listOfBooks[6] = "Stuart Little";
listOfBooks[10] = "Treasure Island";
listOfBooks[12] = "Test";
listOfBooks[14] = "Alice's Adventures in Wonderland";
listOfBooks[20] = "Twenty Thousand Leagues Under the Sea";
listOfBooks[24] = "Peter Pan";
listOfBooks[26] = "Charlotte's Web";
listOfBooks[31] = "A Little Princess";
listOfBooks[32] = "Little Women";
listOfBooks[33] = "Black Beauty";
listOfBooks[35] = "The Merry Adventures of Robin Hood";
listOfBooks[40] = "Robinson Crusoe";
listOfBooks[46] = "Anne of Green Gables";
listOfBooks[50] = "Little House in the Big Woods";
listOfBooks[52] = "Swiss Family Robinson";
listOfBooks[54] = "The Lion, the Witch and the Wardrobe";
listOfBooks[54] = "Heidi";
listOfBooks[66] = "A Winkle in Time";
listOfBooks[100] = "Mary Poppins";
// gets user input
String numberInput = txtNumberInput.getText();
int number = Integer.parseInt(numberInput);
// Linear search to match index number and user input number
for(int i = 0; i < listOfBooks.length - 1; i++) {
if (listOfBooks.get(i) == number) {
txtLinearOutput.setText(listOfBooks[i]);
break;
}
}
*There is a problem with the listOfBooks.get in the if statement. Also I need to apply a binary search that would search the same array just using the binary method. Need help to apply this type of binary search.
How could I make a statement that checks if the int number is equal to an index?
Note that the following code is just an example of what I have to apply. Variables are all for example purposes:
public static Boolean binarySearch(String [ ] A, int left, int right, String V){
int middle;
if (left > right) {
return false;
}
middle = (left + right)/2;
int compare = V.compareTo(A[middle]);
if (compare == 0) {
return true;
}
if (compare < 0) {
return binarySearch(A, left, middle-1, V);
} else {
return binarySearch(A, middle + 1, right, V);
}
}
you can avoid for loop and check condition by just giving number like this: txtLinearOutput.setText(listOfBooks[number-1]);
remove your code
// Linear search to match index number and user input number
for(int i = 0; i < listOfBooks.length - 1; i++) {
if (listOfBooks.get(i) == number) {
txtLinearOutput.setText(listOfBooks[i]);
break;
}
with
try{
int number = Integer.parseInt(numberInput);
if(number>0 && number<101){
txtLinearOutput.setText(listOfBooks[number-1]);
}else{
// out of range
}
}catch(Exception e){
// handle exception here
}
You are comparing if (listOfBooks.get(i) == number) it is wrong, you should compare: if (i == number), becouse you need compare element position.
This isn't a binary search answer. Just an implementation of HashMap. Have a look at it.
HashMap<String, Integer> books = new HashMap();
books.put("abc", 1);
books.put("xyz", 2);
books.put("pqr", 3);
books.put("lmo", 4);
System.out.println(books.getValue("abc");
Using the inbuilt BinarySearch.
String []arr = new String[15];
arr[0] = "abc";
arr[5] = "prq";
arr[7] = "lmo";
arr[10] = "xyz";
System.out.println(Arrays.binarySearch(arr, "lmo"));
How to compare Strings using binary search.
String[] array = new String[4];
array[0] = "abc";
array[1] = "lmo";
array[2] = "pqr";
array[3] = "xyz";
int first, last, middle;
first = 0;
last = array.length - 1;
middle = (first + last) / 2;
String key = "abc";
while (first <= last) {
if (compare(array[middle], key))
first = middle + 1;
else if (array[middle].equals(key)) {
System.out.println(key + " found at location " + (middle) + ".");
break;
} else {
last = middle - 1;
}
middle = (first + last) / 2;
}
if (first > last)
System.out.println(key + " is not found.\n");
}
private static boolean compare(String string, String key) {
// TODO Auto-generated method stub
for (int i = 0; i < Math.min(string.length(), key.length()); ++i)
if (string.charAt(i) < key.charAt(i))
return true;
return false;
}
Your linear search code looks something like this
try{
txtLinearOutput.setText(listOfBooks[yourNumber]);
}
catch(IndexOutOfBoundsException ie){
// prompt that number is not an index
}
catch(Exception e){
// if any other exception is caught
}
What you are doing here:
if (listOfBooks.get(i) == number) {
is that you are matching the content of the array with the input number, which is irrelevant.
You can directly use the input number to fetch the value stored at the index.
For example:
txtLinearOutput.setText(listOfBooks[number-1]);
Additionally, int number = Integer.parseInt(numberInput); should be placed within try-catch block to validate input number parsing. And you can check if the input number is within the range of the array to avoid exceptions like:
try{
int number = Integer.parseInt(numberInput);
// Linear search to match index number and user input number
if (number > 0 && number <=100) {
txtLinearOutput.setText(listOfBooks[number-1]);
} else {
// Display error message
}
} catch(Exception e) {
// Handle exception and display error message
}
And for using binary search, the string array need to be sorted. You can use Arrays.sort() method for sorting it.
And regarding using binary search, you can use Java Arrays Binary Search method

Detail formatter error: java.util.Arrays cannot be resolved to a type

I have developed a BlackBerry application where in I am reading in a HEX String values. The values returned are as follows:
String result = response.toString();
where result is:
["AC36C71DF3CB315A35BFE49A17F483B6","CF5B717ACC460E3C4545BE709E9BCB83","E1EE334738CA4FA14620639DD6750DC3","DD40E2822539C2184B652D1FC3D2B4E6","6AF4B1EAC8D8210D64A944BFD487B9F2"]
These are passed into the following split method to separate the values. The method is as follows:
private static String[] split(String original, String separator) {
Vector nodes = new Vector();
int index = original.indexOf(separator);
while (index >= 0) {
nodes.addElement(original.substring(0, index));
original = original.substring(index + separator.length());
index = original.indexOf(separator);
}
nodes.addElement(original);
String[] result = new String[nodes.size()];
if (nodes.size() > 0) {
for (int loop = 0; loop < nodes.size(); loop++) {
result[loop] = (String) nodes.elementAt(loop);
System.out.println(result[loop]);
}
}
return result;
}
The above array is passed is as the String original in the method. This part is working fine. However, when a single value is passed in as String original, i.e. ["6AF4B1EAC8D8210D64A944BFD487B9F2"], I get an error :
Detail formatter error:java.util.Arrays cannot be resolved to a type.
Please help !!! The values posted above are exact values as read including the parenthesis [] and quotations ""
The Blackberry libraries are based on Java ME and not Java SE. In Java ME some classes have been removed to reduce the runtime footprint such as the Arrays class.
Take a look at the Blackberry JDE java.util package, see there is no Arrays class. So in your code you cannot use methods coming from the Arrays class, you must found a workaround or implement the feature yourself.
Try this split method -
public static String[] split(String strString, String strDelimiter) {
String[] strArray;
int iOccurrences = 0;
int iIndexOfInnerString = 0;
int iIndexOfDelimiter = 0;
int iCounter = 0;
//Check for null input strings.
if (strString == null) {
throw new IllegalArgumentException("Input string cannot be null.");
}
//Check for null or empty delimiter strings.
if (strDelimiter.length() <= 0 || strDelimiter == null) {
throw new IllegalArgumentException("Delimeter cannot be null or empty.");
}
if (strString.startsWith(strDelimiter)) {
strString = strString.substring(strDelimiter.length());
}
if (!strString.endsWith(strDelimiter)) {
strString += strDelimiter;
}
while((iIndexOfDelimiter = strString.indexOf(strDelimiter,
iIndexOfInnerString)) != -1) {
iOccurrences += 1;
iIndexOfInnerString = iIndexOfDelimiter +
strDelimiter.length();
}
strArray = new String[iOccurrences];
iIndexOfInnerString = 0;
iIndexOfDelimiter = 0;
while((iIndexOfDelimiter = strString.indexOf(strDelimiter,
iIndexOfInnerString)) != -1) {
strArray[iCounter] = strString.substring(iIndexOfInnerString,iIndexOfDelimiter);
iIndexOfInnerString = iIndexOfDelimiter +
strDelimiter.length();
iCounter += 1;
}
return strArray;
}

Binary Search Tree Insert Problems (Java)

So I have a setup program reading in country records from a file and my goal is to make an index based on the 3 char letter representation of a country (ex. USA). I am required to use 6 Parallel arrays. LeftChPtr, 3 char Arrays for the Code, DataRecPtr, and RightChPtr.
Here is the method InsertCode it is being sent in the DataRecPtr and the 3 chars in an array.
After all the data is inserted, It is saved to a file and when I look at the file I can tell it's wrong because the pointers aren't correct.
Please help, I am in no way asking you to write code for me I just don't see the problem.
Thanks
N = 0
rootPtr = -1
parentI = 0;
public void InsertCode(short ID, char[] cc)
{
drp = ID;
short i;
codeArray1[N] = cc[0];
codeArray2[N] = cc[1];
codeArray3[N] = cc[2];
leftChPtr[N] = -1;
rightChPtr[N] = -1;
dataRecPtr[N] = drp;
if (rootPtr == -1) //special case - no nodes in BST yet
rootPtr = N;
else //normal case
{
i = rootPtr;
String dataN = "";
dataN += codeArray1[N] + codeArray2[N] + codeArray1[N];
while (i != -1)
{ parentI = i;
String dataI = "";
dataI += codeArray1[i] + codeArray2[i] + codeArray3[i];
if (dataN.compareTo(dataI) < 0)
{
i = leftChPtr[i];
LorR = true;//L
}
else
{
i = rightChPtr[i];
LorR = false;//R
}
}
//i++;?????????????????
if (LorR == true)
leftChPtr[parentI] = N;
else
rightChPtr[parentI] = N;
}
N++;
}
Cant see anything wrong with the insert method apart from LorR should be declared. May be you should check the code for saving into a file.

get string between parentheses [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Regular Expression to find a string included between two characters, while EXCLUDING the delimiters
I'm using a method called Interpreter.eval() of external library "beanshell" that allows to make math operations with Strings and return the solution.
It works fine, but if I want to raise to the second power or get a square root out of this I have to modify the original String that is like
String st ="x = 2+4*a*(b+c)^2"
I need to get the charaters between parentheses to replace "(b+c)^2" to "(b+c)*(b+c)" or "Math.pow((b+c),2)"
How can I do this?
Thanks in advance!
----edit----
Finally I found the solution.
Interpreter interpreter = new Interpreter();
String st = "x = 2+4*1*(2*(1+1)^2)^2 + (4+5)^2";
int index = -2;
char prev;
char post;
int openPar = -1;
if (st.contains("^")) {
index = st.indexOf("^");
while (index != -1) {
prev = st.charAt(index - 1);
post = st.charAt(index + 1);
if (prev == ')') {
int match = 0;
int i = index - 2;
char check = '0';
boolean contiunar = true;
while (contiunar) {
check = st.charAt(i);
if (check == ')')
match++;
if (check == '(') {
if (match == 0) {
openPar = i;
contiunar = false;
} else
match = match - 1;
}
i = i - 1;
}
String rep = st.substring(openPar + 1, index - 1);
String resultado = "";
try {
interpreter.eval("r= Math.pow(" + rep + "," + post
+ ")");
resultado = interpreter.get("r").toString();
} catch (EvalError e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
st = st.replace("(" + rep + ")^" + post, resultado);
} else {
st = st.replace(prev + "^" + post, prev + "*" + prev);
}
index = st.indexOf("^");
}
}
With this I modified the original String x = 2+4*1*(2*(1+1)^2)^2+(4+5)^2 (for example)
to x=2+4*1*64+81
first it search the first "^"
get previous char
and if there are ")"
search previous char while finds "(" But if finds ")" before of "(" has to find 2 "("; one to open internal parentheses and the second open the parentheses I want to pow.
This is in case of "(2+(3+4)+5)^2" ---> return "2+(3+4)+5" instead of "3+4)+5".
now replace to correct expresion Math.pow("result","2")" and calculate step by step
(1+1)^2 = 4
(2*4)^2 = 64
(4+5)^2 = 81
finally now I can calculate the retun with Interpreter.eval()
Thanks a lot for the answers!
try the following code to do your task
String originalString ="x = 2+4*a*(b+c)^2";
String stringToInsert = "Math.pow((b+c),2)";
int startIndex = originalString.indexOf("(");
int endIndex = originalString.indexOf(")");
String firstPortion = originalString.substring(0,startIndex);
String lastPortion = originalString.substring(endIndex+1);
String finalString = firstPortion + stringToInsert + lastPortion;
System.out.println("finalString : "+finalString);
You will need to parse the string. You could write a complete parser and go through it character by character.
Otherwise, if there is a specific flowchart you have in mind (using the operators), use the String.split(\"*(...) functionality where you can essentially create tokens based on whatever your delimeters are.
Hope this helps.
Of course you need to parse the String. You can convert it to intermediate state ( which you can execute after very quickly) . You can see the following link maybe it can help you http://en.wikipedia.org/wiki/Reverse_Polish_notation

Java String parsing - {k1=v1,k2=v2,...}

I have the following string which will probably contain ~100 entries:
String foo = "{k1=v1,k2=v2,...}"
and am looking to write the following function:
String getValue(String key){
// return the value associated with this key
}
I would like to do this without using any parsing library. Any ideas for something speedy?
If you know your string will always look like this, try something like:
HashMap map = new HashMap();
public void parse(String foo) {
String foo2 = foo.substring(1, foo.length() - 1); // hack off braces
StringTokenizer st = new StringTokenizer(foo2, ",");
while (st.hasMoreTokens()) {
String thisToken = st.nextToken();
StringTokenizer st2 = new StringTokenizer(thisToken, "=");
map.put(st2.nextToken(), st2.nextToken());
}
}
String getValue(String key) {
return map.get(key).toString();
}
Warning: I didn't actually try this; there might be minor syntax errors but the logic should be sound. Note that I also did exactly zero error checking, so you might want to make what I did more robust.
The speediest, but ugliest answer I can think of is parsing it character by character using a state machine. It's very fast, but very specific and quite complex. The way I see it, you could have several states:
Parsing Key
Parsing Value
Ready
Example:
int length = foo.length();
int state = READY;
for (int i=0; i<length; ++i) {
switch (state) {
case READY:
//Skip commas and brackets
//Transition to the KEY state if you find a letter
break;
case KEY:
//Read until you hit a = then transition to the value state
//append each letter to a StringBuilder and track the name
//Store the name when you transition to the value state
break;
case VALUE:
//Read until you hit a , then transition to the ready state
//Remember to save the built-key and built-value somewhere
break;
}
}
In addition, you can implement this a lot faster using StringTokenizers (which are fast) or Regexs (which are slower). But overall, individual character parsing is most likely the fastest way.
If the string has many entries you might be better off parsing manually without a StringTokenizer to save some memory (in case you have to parse thousands of these strings, it's worth the extra code):
public static Map parse(String s) {
HashMap map = new HashMap();
s = s.substring(1, s.length() - 1).trim(); //get rid of the brackets
int kpos = 0; //the starting position of the key
int eqpos = s.indexOf('='); //the position of the key/value separator
boolean more = eqpos > 0;
while (more) {
int cmpos = s.indexOf(',', eqpos + 1); //position of the entry separator
String key = s.substring(kpos, eqpos).trim();
if (cmpos > 0) {
map.put(key, s.substring(eqpos + 1, cmpos).trim());
eqpos = s.indexOf('=', cmpos + 1);
more = eqpos > 0;
if (more) {
kpos = cmpos + 1;
}
} else {
map.put(key, s.substring(eqpos + 1).trim());
more = false;
}
}
return map;
}
I tested this code with these strings and it works fine:
{k1=v1}
{k1=v1, k2 = v2, k3= v3,k4 =v4}
{k1= v1,}
Written without testing:
String result = null;
int i = foo.indexOf(key+"=");
if (i != -1 && (foo.charAt(i-1) == '{' || foo.charAt(i-1) == ',')) {
int j = foo.indexOf(',', i);
if (j == -1) j = foo.length() - 1;
result = foo.substring(i+key.length()+1, j);
}
return result;
Yes, it's ugly :-)
Well, assuming no '=' nor ',' in values, the simplest (and shabby) method is:
int start = foo.indexOf(key+'=') + key.length() + 1;
int end = foo.indexOf(',',i) - 1;
if (end==-1) end = foo.indexOf('}',i) - 1;
return (start<end)?foo.substring(start,end):null;
Yeah, not recommended :)
Adding code to check for existance of key in foo is left as exercise to the reader :-)
String foo = "{k1=v1,k2=v2,...}";
String getValue(String key){
int offset = foo.indexOf(key+'=') + key.length() + 1;
return foo.substring(foo.indexOf('=', offset)+1,foo.indexOf(',', offset));
}
Please find my solution:
public class KeyValueParser {
private final String line;
private final String divToken;
private final String eqToken;
private Map<String, String> map = new HashMap<String, String>();
// user_uid=224620; pass=e10adc3949ba59abbe56e057f20f883e;
public KeyValueParser(String line, String divToken, String eqToken) {
this.line = line;
this.divToken = divToken;
this.eqToken = eqToken;
proccess();
}
public void proccess() {
if (Strings.isNullOrEmpty(line) || Strings.isNullOrEmpty(divToken) || Strings.isNullOrEmpty(eqToken)) {
return;
}
for (String div : line.split(divToken)) {
if (Strings.isNullOrEmpty(div)) {
continue;
}
String[] split = div.split(eqToken);
if (split.length != 2) {
continue;
}
String key = split[0];
String value = split[1];
if (Strings.isNullOrEmpty(key)) {
continue;
}
map.put(key.trim(), value.trim());
}
}
public String getValue(String key) {
return map.get(key);
}
}
Usage
KeyValueParser line = new KeyValueParser("user_uid=224620; pass=e10adc3949ba59abbe56e057f20f883e;", ";", "=");
String userUID = line.getValue("user_uid")

Categories