How do I split strings in J2ME? - java

How do I split strings in J2ME in an effective way?
There is a StringTokenizer or String.split(String regex) in the standard edition (J2SE), but they are absent in the micro edition (J2ME, MIDP).

There are a few implementations of a StringTokenizer class for J2ME. This one by Ostermiller will most likely include the functionality you need
See also this page on Mobile Programming Pit Stop for some modifications and the following example:
String firstToken;
StringTokenizer tok;
tok = new StringTokenizer("some|random|data","|");
firstToken= tok.nextToken();

There is no built in method to split strings. You have to write it on your own using
String.indexOf() and String.substring(). Not hard.

String.split(...) is available in J2SE, but not J2ME.
You are required to write your own algorithm: related post with sample solution.

I hope this one will help you... This is my own implementation i used in my application. Of course this can still be optimized. i just do not have time to do it... and also, I am working on StringBuffer here. Just refactor this to be able to use String instead.
public static String[] split(StringBuffer sb, String splitter){
String[] strs = new String[sb.length()];
int splitterLength = splitter.length();
int initialIndex = 0;
int indexOfSplitter = indexOf(sb, splitter, initialIndex);
int count = 0;
if(-1==indexOfSplitter) return new String[]{sb.toString()};
while(-1!=indexOfSplitter){
char[] chars = new char[indexOfSplitter-initialIndex];
sb.getChars(initialIndex, indexOfSplitter, chars, 0);
initialIndex = indexOfSplitter+splitterLength;
indexOfSplitter = indexOf(sb, splitter, indexOfSplitter+1);
strs[count] = new String(chars);
count++;
}
// get the remaining chars.
if(initialIndex+splitterLength<=sb.length()){
char[] chars = new char[sb.length()-initialIndex];
sb.getChars(initialIndex, sb.length(), chars, 0);
strs[count] = new String(chars);
count++;
}
String[] result = new String[count];
for(int i = 0; i<count; i++){
result[i] = strs[i];
}
return result;
}
public static int indexOf(StringBuffer sb, String str, int start){
int index = -1;
if((start>=sb.length() || start<-1) || str.length()<=0) return index;
char[] tofind = str.toCharArray();
outer: for(;start<sb.length(); start++){
char c = sb.charAt(start);
if(c==tofind[0]){
if(1==tofind.length) return start;
inner: for(int i = 1; i<tofind.length;i++){ // start on the 2nd character
char find = tofind[i];
int currentSourceIndex = start+i;
if(currentSourceIndex<sb.length()){
char source = sb.charAt(start+i);
if(find==source){
if(i==tofind.length-1){
return start;
}
continue inner;
} else {
start++;
continue outer;
}
} else {
return -1;
}
}
}
}
return index;
}

That depends on what exactly you want to achieve, but the function String.substring() will be in there somewhere:
String myString = "Hello World";
This will print the substring starting from index 6 to the end of the string:
System.out.println(myString.substring(6));
This will print the substring starting from index 0 until index 5:
System.out.println(myString.substring(0,5));
Output of all the code above:
World
Hello
Combine this with the other String functions (indexOf(). etc.) to achieve the desired effect!
Re-reading your question, it looks as though you may have been looking for String.split(). This will split your input string into an array of strings based on a given regex:
String myString = "Hi-There-Gang";
String[] splitStrings = myString.split("-");
This will result in the splitStrings array containing three string, "Hi", "There" and "Gang".
Re-reading your question again, String.split is not available in J2ME, but the same effect can be achieved with substring and indexOf.

public static Vector splitDelimiter(String text, char delimiter) {
Vector splittedString = null;
String text1 = "";
if (text != null) {
splittedString = new Vector();
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == delimiter) {
splittedString.addElement(text1);
text1 = "";
} else {
text1 += text.charAt(i);
// if(i==text.length()-1){
// splittedString.addElement(text1);
// }
}
}
splittedString.addElement(text1);
}
return s
}
You can use this method for splitting a delimiter.

In J2ME no split, but you can use this code for split.This code works with only 1 simbol delimiter!!!
Use NetBeans.File\Create Project\ Java ME\ MobileApplication\Set project name(split)\Set checkmark.Delete all code in your (Midlet.java).Copy this code and past in your (Midlet.java).
//IDE NetBeans 7.3.1
//author: UserSuperPupsik
//email: usersuperpupsik#gmail.com
package split;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import java.util.Vector;
public class Midlet extends MIDlet {
public String e1;
public Vector v=new Vector();
public int ma;
int IsD=0;
int vax=0;
public String out[];
private Form f;
public void split0(String text,String delimiter){
if (text!=""){
IsD=0;
int raz=0;
//v.removeAllElements();
v.setSize(0);
int io;
String temp="";
int ni=(text.length()-1);
for(io=0;io<=ni;io++){
char ch=text.charAt(io);
String st=""+ch;
if(io==0 && st.equals(delimiter)){IsD=1;}
if(!st.equals(delimiter)){temp=temp+st;} //Not equals (!=)
else if(st.equals(delimiter)&&temp!="")//equals (==)
{
IsD=1;
//f.append(temp);
v.addElement(temp);
temp="";
}
if(io==ni && temp!="") {
v.addElement(temp);
temp="";
}
if((io==ni)&&IsD==0&&temp!=""){v.addElement(temp);}
}
if(v.size()!=0){
ma=(v.size());
out=new String[ma];
v.copyInto(out);
}
//else if(v.size()==0){IsD=1; }
}
}
public void method1(){
f.append("\n");
f.append("IsD: " +IsD+"");
if (v.size()!=0){
for( vax=0;vax<=ma-1;vax++){
f.append("\n");
f.append(out[vax]);
}
}
}
public void startApp() {
f=new Form("Hello J2ME!");
Display.getDisplay(this).setCurrent(f);
f.append("");
split0("Hello.World.Good...Luck.end" , ".");
method1();
split0(".",".");
method1();
split0(" First WORD2 Word3 "," ");
method1();
split0("...",".");
method1();
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
Splited elements located in array called (out).For Example out[1]:Hello.
Good Luck!!!

Another alternative solution:
public static Vector split(String stringToSplit, String separator){
if(stringToSplit.length<1){
return null;
}
Vector stringsFound = new Vector();
String remainingString = stringToSplit;
while(remainingString.length()>0){
int separatorStartingIndex = remainingString.indexOf(separator);
if(separatorStartingIndex==-1){
// Not separators found in the remaining String. Get substring and finish
stringsFound.addElement(remainingString);
break;
}
else{
// The separator is at the beginning of the String,
// Push the beginning at the end of separator and continue
if(remainingString.startsWith(separator)){
remainingString = remainingString.substring(separator.length());
}
// The separator is present and is not the beginning, add substring and continue
else{
stringsFound.addElement(remainingString.substring(0, separatorStartingIndex));
remainingString = remainingString.substring(separatorStartingIndex + separator.length());
}
}
}
return stringsFound;
}

Related

Given a Morse String with out any spaces, how to find the no. of words it can represent irrespective of the meaning

Given A morse String eg. aet = ".- . -" if the spaces are removed it will become an ambiguous morse string ".-.-" which can represent "aet","eta","ent","etet" etc.
the problem is to find the no.of words that the morse string without spaces can represent irrespective of the meaning of the words. The constraint is that the new word which is formed should be the same size of the input i.e "aet" = "ent" and other words like "etet" should be discarded.
i implemented a recursive solution for some reason it is not working. below is my code and thinking of converting this to DP approach to increase time efficiency. Can some one help to point out the mistake in the below code and is DP a right approach to follow for this problem? Thanks in advance!!
EDIT 1 :- The program gives me an output but not the correct one. for ex. for the morse String representing aet = ".- . -" if given without any spaces to the program ".-.-" it should give an out put "3" i.e 3 words can be formed that is of the same size as the input including the input "aet","eta","ent" but it gives me an output "1". I think there is some thing wrong with the recursive calls.
The approach used here is to simply cut the morse string in a place where first valid morse code is encountered and the repeat the process with the rest of the string untill 3 such valid morse code are found and check whether whole morse string is consumed. if consumed increment the word count and repeat the process for different values of substring size(end variable in the below code).
I hope this helps!!.Tried my best to explain as clearly as I could.
import java.util.*;
import java.io.*;
import java.math.*;
import java.text.*;
public class MorseCode2 {
static Map<String,String> morseCode;
static Map<String,String> morseCode2;
static int count = 0;
public static void main(String args[]){
String[] alpha = {"a","b","c","d","e","f","g","h","i","j","k",
"l","m","n","o","p","q","r","s","t","u","v",
"w","x","y","z"};
String[] morse = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",
".--","-..-","-.--","--.."};
morseCode = new HashMap<String,String>();
morseCode2 = new HashMap<String,String>();
for(int i = 0;i<26;i++){
morseCode.put(morse[i],alpha[i]);
}
for(int i = 0;i<26;i++){
morseCode2.put(alpha[i],morse[i]);
}
Scanner in = new Scanner(System.in);
String input = in.next();
String morseString = "";
for(int j = 0; j< input.length(); j++){
morseString += morseCode2.get(input.charAt(j)+"");
}
countPossibleWord(morseString,input.length(),0,1,0);
System.out.println(count);
in.close();
}
public static void countPossibleWord(String s,int inputSize,int start,int end,int tempCount){
if(start >= s.length() || end > s.length()){
return;
}
if(tempCount>inputSize){
return;
}
String sub = s.substring(start, end);
if(sub.length()>4){
return;
}
if(morseCode.get(sub)!=null){
tempCount++;
countPossibleWord(s,inputSize,end,end+1,tempCount);
}
else{
countPossibleWord(s,inputSize,start,end+1,tempCount);
}
if(tempCount == inputSize && end == s.length()){
count++;
}
countPossibleWord(s,inputSize,start,end+1,0);
}
}
EDIT 2 :- Thank you all for your Responses and Extremely sorry for the confusing code, will surely try to improve on writing neat and clear code. learnt a lot from your replies!!
And i also some how made the code work, the problem was I passed wrong argument which changed the state of the recursive calls. Instead of passing "tempCount-1" for the last argument in the last function call in the method "countPossibleWord" i passed "0" this altered the state. found this after running through the code manually for larger inputs. below is the corrected method
public static void countPossibleWord(String s,int inputSize,int start,int end,int tempCount){
if(start >= s.length() || end > s.length()){
return;
}
if(tempCount>inputSize){
return;
}
String sub = s.substring(start, end);
if(sub.length()>4){
return;
}
if(morseCode.get(sub)!=null){
tempCount++;
countPossibleWord(s,inputSize,end,end+1,tempCount);
}
else{
countPossibleWord(s,inputSize,start,end+1,tempCount);
}
if(tempCount == inputSize && end == s.length()){
count++;
}
countPossibleWord(s,inputSize,start,end+1,tempCount-1);
}
}
If you like to have a recursive function, you should be clear about your parameters (use as few as possible) as well as when to step down and when to go up again.
My solution would look something like
public static int countPossibleWord(String strMorse, String strAlpha, int inputSize) {
if (strMorse.length() > 0) { // still input to process
if (strAlpha.length() >= inputSize)
return 0; // String already has wrong size
int count = 0;
for (int i = 0; i < morse.length; i++) { // try all morse codes
if (strMorse.startsWith(morse[i])) { // on the beginning of the given string
count += countPossibleWord(strMorse.substring(morse[i].length()), strAlpha+alpha[i], inputSize);
}
}
return count;
} else {
if( strAlpha.length() == inputSize ) {
System.out.println( strAlpha );
return 1; // one solution has been found
} else {
return 0; // String has wrong size
}
}
}
Your morse and alpha arrays need to be static variables for this to work.
Note that there is only one situation where the recursion will step down: when there is some input left and the size limit is not reached. Then it will check for the next possible letter in the loop.
All other cases will lead the recursion to go one step up again - and when going up, it will return the number of solutions found.
Call it like this:
System.out.println(countPossibleWord(morseString, "", input.length() ));
The fact that you use a class variable instead of the returned value of the recursive function makes it extremely unclear. Even for you as #Thomas Weller said. You should clarify the possible cases when a count one more letter. I deleted eclipse, hence I coded it in C, I hope I will still help you to understand the algo :(understand char* as string)
char morse[26][5] = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",
".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
int countPossibleWord(char* s, int inputSize, int start, char* buffer, int sizeBuff){
if(start == inputSize){
if(sizeBuff == 0) return 1;
else return 0;
}
char buff[sizeBuff+2]; //
strncpy(buff, buffer, sizeBuff);//
buff[sizeBuff] = s[start]; // buff = buff+s[start]
buff[sizeBuff+1] = '\0'; //
for(int i = 0; i < 26; ++i){
//run the equivalent of your map to find a match
if(strcmp(buff, morse[i]) == 0)
return countPossibleWord(s, inputSize, start+1, "", 0) + countPossibleWord(s, inputSize, start+1, buff, sizeBuff+1);
}
return countPossibleWord(s, inputSize, start+1, buff, sizeBuff+1);
}
The problem with your code is, that you don't understand it any more, because it's not clean as described by Robert C. Martin. Compare your code to the following. This is certainly still not the cleanest, but I think you can understand what it does. Tell me if you don't.
Consider this main program:
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
public class Program {
public static void main(String[] args) {
String morsetext = enterTextOnConsole();
MorseTable morseTable = new MorseTable();
MorseCode code = convertToMorseCodeWithoutSpaces(morsetext, morseTable);
List<String> guesses = getAllPossibleMeanings(code, morseTable);
List<String> guessesOfSameLength = filterForSameLength(morsetext, guesses);
printListOnConsole(guessesOfSameLength);
}
private static void printListOnConsole(List<String> guessesOfSameLength) {
for (String text : guessesOfSameLength) {
System.out.println(text);
}
}
private static List<String> filterForSameLength(String morsetext, List<String> guesses) {
List<String> guessesOfSameLength = new LinkedList<String>();
for (String guess : guesses) {
if (guess.length() == morsetext.length())
{
guessesOfSameLength.add(guess);
}
}
return guessesOfSameLength;
}
private static List<String> getAllPossibleMeanings(MorseCode code, MorseTable morseTable) {
MorseCodeGuesser guesser = new MorseCodeGuesser(morseTable);
List<String> guesses = guesser.guess(code);
return guesses;
}
private static MorseCode convertToMorseCodeWithoutSpaces(String morsetext, MorseTable morseTable) {
MorseCode code = new MorseCode(morseTable);
code.fromText(morsetext);
code.stripSpaces();
return code;
}
private static String enterTextOnConsole() {
Scanner scanner = new Scanner(System.in);
String text = scanner.next();
scanner.close();
return text;
}
}
and the following MorseTable class:
import java.util.HashMap;
import java.util.Map;
public class MorseTable {
private static final Map<String, String> morseTable;
private static int longestCode = -1;
static
{
morseTable = new HashMap<String, String>();
morseTable.put("a", ".-");
morseTable.put("b", "-...");
morseTable.put("c", "-.-.");
morseTable.put("e", ".");
morseTable.put("t", "-");
morseTable.put("n", "-.");
// TODO: add more codes
for (String code : morseTable.values()) {
longestCode = Math.max(longestCode, code.length());
}
}
public String getMorseCodeForCharacter(char c) throws IllegalArgumentException {
String characterString = ""+c;
if (morseTable.containsKey(characterString)) {
return morseTable.get(characterString);
}
else {
throw new IllegalArgumentException("No morse code for '"+characterString+"'.");
}
}
public int lengthOfLongestMorseCode() {
return longestCode;
}
public String getTextForMorseCode(String morseCode) throws IllegalArgumentException {
for (String key : morseTable.keySet()) {
if (morseTable.get(key).equals(morseCode)) {
return key;
}
}
throw new IllegalArgumentException("No character for morse code '"+morseCode+"'.");
}
}
and the MorseCode class
public class MorseCode {
public MorseCode(MorseTable morseTable)
{
_morseTable = morseTable;
}
final MorseTable _morseTable;
String morseCode = "";
public void fromText(String morsetext) {
for(int i=0; i<morsetext.length(); i++) {
char morseCharacter = morsetext.charAt(i);
morseCode += _morseTable.getMorseCodeForCharacter((morseCharacter));
morseCode += " "; // pause between characters
}
}
public void stripSpaces() {
morseCode = morseCode.replaceAll(" ", "");
}
public MorseCode substring(int begin, int end) {
MorseCode subcode = new MorseCode(_morseTable);
try{
subcode.morseCode = morseCode.substring(begin, end);
} catch(StringIndexOutOfBoundsException s) {
subcode.morseCode = "";
}
return subcode;
}
public MorseCode substring(int begin) {
return substring(begin, morseCode.length());
}
public String asPrintableString() {
return morseCode;
}
public boolean isEmpty() {
return morseCode.isEmpty();
}
}
and last not least, the MorseCodeGuesser
import java.util.LinkedList;
import java.util.List;
public class MorseCodeGuesser {
private final MorseTable _morseTable;
public MorseCodeGuesser(MorseTable morseTable) {
_morseTable = morseTable;
}
public List<String> guess(MorseCode code) {
List<String> wordList = new LinkedList<String>();
if (code.isEmpty()) return wordList;
for(int firstCodeLength=1; firstCodeLength<=_morseTable.lengthOfLongestMorseCode(); firstCodeLength++) {
List<String> guesses = guess(code, firstCodeLength);
wordList.addAll(guesses);
}
return wordList;
}
private List<String> guess(MorseCode code, int firstCodeLength) {
MorseCode firstCode = code.substring(0, firstCodeLength);
String firstCharacter;
try{
firstCharacter = _morseTable.getTextForMorseCode(firstCode.asPrintableString());
} catch(IllegalArgumentException i) {
return new LinkedList<String>(); // no results for invalid code
}
MorseCode remainingCode = code.substring(firstCodeLength);
if (remainingCode.isEmpty()) {
List<String> result = new LinkedList<String>();
result.add(firstCharacter); // sole result if nothing is left
return result;
}
List<String> result = new LinkedList<String>();
List<String> remainingPossibilities = guess(remainingCode);
for (String possibility : remainingPossibilities) {
result.add(firstCharacter + possibility); // combined results
}
return result;
}
}
I have pasted my own solution to it. I have followed DFS and it is giving the correct answer for the given problem statement. Please ask if there are any queries.
alpha =["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
key = [".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--",
"-..-","-.--","--.."]
dic = dict(list(zip(key,alpha)))
def morse_code(morse,count,res,char,length):
global dic
if count == length - 1:
if morse[char:] in dic:
res = res + 1
return res
word = ''
for i in range(char,len(morse)):
word = word + morse[i]
if word not in dic:
continue
else:
count = count + 1
res = morse_code(morse,count,res,i+1,length)
count = count - 1
return res
if __name__ = 'main'
inp = input()
morse = ''
for i in inp:
morse = morse + key[ord(i)-ord('a')]
result = morse_code(morse,0,0,0,len(inp))
print(result)

Write a method to replace all spaces in a string with '%20'?

I have a question about a programming problem from the book Cracking The Code Interview by Gayl Laakmann McDowell, 5th Edition.
I'm not sure what is wrong with my answer? It varies a lot from the answer given in the book.
public String replace(String str){
String[] words = str.split(" ");
StringBuffer sentence = new StringBuffer();
for(String w: words){
sentence.append("%20");
sentence.append(w);
}
return sentence.toString();
}
Question in the book says:
Note: if implementing in Java, please use a character array so that
you can perform this operation in place.
It also says that the char array that you get as input is long enough to hold the modified string.
By using split and StringBuffer you use additional O(n) space. That's why your answer varies a lot and is incorrect (apart from adding additional "%20").
In this loop, the program adds %20 before each word:
for(String w: words){
sentence.append("%20");
sentence.append(w);
}
That will produce incorrect results, for example for a b it will give %20a%20b.
There's a much simpler solution:
public String replace(String str) {
return str.replaceAll(" ", "%20");
}
Or, if you really don't want to use .replaceAll, then write like this:
public String replace(String str) {
String[] words = str.split(" ");
StringBuilder sentence = new StringBuilder(words[0]);
for (int i = 1; i < words.length; ++i) {
sentence.append("%20");
sentence.append(words[i]);
}
return sentence.toString();
}
You can also do the following, which replaces any space
String s = "Hello this is a string!";
System.out.println(replaceSpace(s, "%20"));
public static String replaceSpace(String s, String replacement) {
String ret = s.replaceAll(" *", replacement);
return ret;
}
Gives
Hello%20this%20is%20a%20string!
One of the simplest way:
public void replaceAll( String str )
{
String temp = str.trim();
char[] arr = temp.toCharArray();
StringBuffer sb = new StringBuffer();
for( int i = 0; i < arr.length; i++ )
{
if( arr[i] == ' ' )
{
sb.append( "%20" );
}
else
{
sb.append( arr[i] );
}
}
}
private static String applyReplaceOperationWithCount(String str) {
if (StringUtils.isEmpty(str)) { //if string is null or empty, return it
return str;
}
char[] strChar = str.toCharArray();
int count = 0; //count spaces in the string to recalculate the array length
for (char c : strChar) {
if (c == ' ') {
count++;
}
}
if (count == 0) { // if there are no spaces in the string, return it
return str;
}
int length = strChar.length;
char[] newChar = new char[length + (count * 2)]; // 1 char will be replaced by 3 chars. So the new length should be count*2 larger than original
int index = 0;
for (char c : strChar) {
if (c != ' ') { // if char is not a space just push it in the next available location
newChar[index++] = c;
} else { // if char is a space just push %,2,0
newChar[index++] = '%';
newChar[index++] = '2';
newChar[index++] = '0';
}
}
return new String(newChar); // convert the new array into string
}
I am using matches and replaceAll it works well.
public class ReplaceSpaces {
public static void main(String[] args) {
String text = " Abcd olmp thv ";
if(text.matches(".*\\s+.*")){
System.out.println("Yes I see white space and I am replacing it");
String newText = text.replaceAll("\\s+", "%20");
System.out.println(newText);
}
else{
System.out.println("Nope I dont see white spaces");
}
}
}
Output
Yes I see white space and I am replacing it
%20Abcd%20olmp%20thv%20
public static String replaceSpaceInString(String string,String toreplace){
String replacedString = "";
if(string.isEmpty()) return string;
string = string.trim();
if(string.indexOf(" ") == -1)return string;
else{
replacedString = string.replaceAll("\\s+",toreplace);
}
return replacedString;
}

Decompressing String method

I need help with decompressing method. I have a working Compress method. Any suggestions as far as what I need to consider? Do I need parseInt or else....? Appreciate the advice. Here is what I have so far. If s = "ab3cca4bc", then it should return "abbbccaaaabc", for example of decompress.
class RunLengthCode {
private String pText, cText;
public RunLengthCode () {
pText = "";
cText = "";
}
public void setPText (String newPText) {
pText = newPText;
}
public void setCText (String newCText) {
cText = newCText;
}
public String getPText () {
return pText;
}
public String getCText () {
return cText;
}
public void compress () { // compresses pText to cText
String ans = "";
for (int i = 0; i < pText.length(); i++) {
char current = pText.charAt(i);
int cnt = 1;
String temp = "";
temp = temp + current;
while (i < pText.length() - 1 && (current == pText.charAt(i + 1))) {
cnt++;
i++;
temp = temp + current;
}
if (cnt > 2) {
ans = ans + current;
ans = ans + cnt;
}
else
ans = ans + temp;
setCText(ans);
}
}
public void decompress () {
}
}
public class {
public static void main(String [] args) {
Scanner in = new Scanner(System.in);
RunLengthCode myC = new RunLengthCode();
String pText, cText;
System.out.print("Enter a plain text consisting of only lower-case alphabets and spaces:");
pText = in.nextLine();
myC.setPText(pText);
myC.compress();
System.out.println(pText+" => "+myC.getCText());
System.out.print("Enter a compressed text consisting of only lower-case alphabets, spaces and digits:");
cText = in.nextLine();
myC.setCText(cText);
myC.decompress();
System.out.println(cText+" => "+myC.getPText());
}
}
You could create break the string into regx groups and combine them.
The following pattern works
(([A-Za-z]+[\d]*))
This will break your string "ab3cca4bc" into groups of
"ab3", "cca4", "bc"
So in a loop if the last character is a digit, you could multiply the character before it that many times.
Ok, so you've got an input string that looks like ab3cca4bc
1.) Loop over the length of the input String
2.) During each loop iteration, use the String.charAt(int) method to pick up the individual character
3.) The Character class has an isDigit(char) function that you can use to determine if a character is a number or not. You can then safely use Integer.parseInt(String) (you can use myChar+"" to convert a char into a String)
4.) If the char in question is a number, then you'll need to have an inner loop to repeat the previous character the correct number of times. How will you know what the last character was? Maybe have a variable that's instantiated outside the loop that you update each time you add a character on the end?

How can I split a string into words in Java without using String.split()?

My teacher specifically requested that we split a sentence into words without using String.split(). I've done it using a Vector (which we haven't learned), a while-loop, and substrings. What are other ways of accomplishing this? (preferably without using Vectors/ArrayLists).
I believe that your teacher is asking you to process the string yourself (without using any other libraries to do it for you). Check to see if this is the case - if you can use them, there are things such as StringTokenizer, Pattern, and Scanner to facilitate string processing.
Otherwise...
You will need a list of word separators (such as space, tab, period, etc...) and then walk the array, building a string a character at a time until you hit the word separator. After finding a complete word (you have encountered a word separator character), save it the variable out into your structure (or whatever is required), reset the variable you are building the word in and continue.
Parsing the string character by character, copying each character into a new String, and stopping when you reach a white space character. Then start a new string and continue until you reach the end of the original string.
You can use java.util.StringTokenizer to split a text using desired delimiter. Default delimiter is SPACE/TAB/NEW_LINE.
String myTextToBeSplit = "This is the text to be split into words.";
StringTokenizer tokenizer = new StringTokenizer( myTextToBeSplit );
while ( tokinizer.hasMoreTokens()) {
String word = tokinizer.nextToken();
System.out.println( word ); // word you are looking in
}
As an alternate you can also use java.util.Scanner
Scanner s = new Scanner(myTextToBeSplit).useDelimiter("\\s");
while( s.hasNext() ) {
System.out.println(s.next());
}
s.close();
You can use java.util.Scanner.
import java.util.Arrays;
public class ReverseTheWords {
public static void main(String[] args) {
String s = "hello java how do you do";
System.out.println(Arrays.toString(ReverseTheWords.split(s)));
}
public static String[] split(String s) {
int count = 0;
char[] c = s.toCharArray();
for (int i = 0; i < c.length; i++) {
if (c[i] == ' ') {
count++;
}
}
String temp = "";
int k = 0;
String[] rev = new String[count + 1];
for (int i = 0; i < c.length; i++) {
if (c[i] == ' ') {
rev[k++] = temp;
temp = "";
} else
temp = temp + c[i];
}
rev[k] = temp;
return rev;
}
}
YOu can use StringTokenizer
http://www.java-samples.com/showtutorial.php?tutorialid=236
Or use a Pattern (also known as a regular expression) to try to match the words.
Use a Scanner with ctor (String)
regular expressions and match
StringTokenizer
iterating yourself char by char
recursive iteration
Without using a Vector/List (and without manually re-implementing their ability to re-size themselves for your function), you can take advantage of the simple observation that a string of length N cannot have more than (N+1)/2 words (in integer division). You can declare an array of strings of that size, populate it the same way you populated that Vector, and then copy the results to an array of the size of the number of words you found.
So:
String[] mySplit( String in ){
String[] bigArray = new String[ (in.length()+1)/2 ];
int numWords = 0;
// Populate bigArray with your while loop and keep
// track of the number of words
String[] result = new String[numWords];
// Copy results from bigArray to result
return result;
}
public class MySplit {
public static String[] mySplit(String text,String delemeter){
java.util.List<String> parts = new java.util.ArrayList<String>();
text+=delemeter;
for (int i = text.indexOf(delemeter), j=0; i != -1;) {
parts.add(text.substring(j,i));
j=i+delemeter.length();
i = text.indexOf(delemeter,j);
}
return parts.toArray(new String[0]);
}
public static void main(String[] args) {
String str="012ab567ab0123ab";
String delemeter="ab";
String result[]=mySplit(str,delemeter);
for(String s:result)
System.out.println(s);
}
}
public class sha1 {
public static void main(String[] args) {
String s = "hello java how do you do";
System.out.println(Arrays.toString(sha1.split(s)));
}
public static String[] split(String s) {
int count = 0;
char[] c = s.toCharArray();
for (int i = 0; i < c.length; i++) {
if (c[i] == ' ') {
count++;
}
}
String temp = "";
int k = 0;
String[] rev = new String[count + 1];
for (int i = c.length-1; i >= 0; i--) {
if (c[i] == ' ') {
rev[k++] = temp;
temp = "";
} else
temp = temp + c[i];
}
rev[k] = temp;
return rev;
}
}
Simple touch.! Improve if you want to.
package com.asif.test;
public class SplitWithoutSplitMethod {
public static void main(String[] args) {
split('#',"asif#is#handsome");
}
static void split(char delimeter, String line){
String word = "";
String wordsArr[] = new String[3];
int k = 0;
for(int i = 0; i <line.length(); i++){
if(line.charAt(i) != delimeter){
word+= line.charAt(i);
}else{
wordsArr[k] = word;
word = "";
k++;
}
}
wordsArr[k] = word;
for(int j = 0; j <wordsArr.length; j++)
System.out.println(wordsArr[j]);
}
}
Please try this .
public static String[] mysplit(String mystring) {
String string=mystring+" "; //append " " bcz java string does not hava any ending character
int[] spacetracker=new int[string.length()];// to count no. of spaces in string
char[] array=new char[string.length()]; //store all non space character
String[] tokenArray=new String[string.length()];//to return token of words
int spaceIndex=0;
int parseIndex=0;
int arrayIndex=0;
int k=0;
while(parseIndex<string.length())
{
if(string.charAt(parseIndex)==' '||string.charAt(parseIndex)==' ')
{
spacetracker[spaceIndex]=parseIndex;
spaceIndex++;
parseIndex++;
}else
{
array[arrayIndex]=string.charAt(parseIndex);
arrayIndex++;
parseIndex++;
}
}
for(int i=0;i<spacetracker.length;i++)
{
String token="";
for(int j=k;j<(spacetracker[i])-i;j++)
{
token=token+array[j];
k++;
}
tokenArray[i]=token;
//System.out.println(token);
token="";
}
return tokenArray;
}
Hope this helps
import java.util.*;
class StringSplit {
public static void main(String[] args)
{
String s="splitting a string without using split()";
ArrayList<Integer> al=new ArrayList<Integer>(); //Instead you can also use a String
ArrayList<String> splitResult=new ArrayList<String>();
for(int i=0;i<s.length();i++)
if(s.charAt(i)==' ')
al.add(i);
al.add(0, 0);
al.add(al.size(),s.length());
String[] words=new String[al.size()];
for(int j=0;j<=words.length-2;j++)
splitResult.add(s.substring(al.get(j),al.get(j+1)).trim());
System.out.println(splitResult);
}
}
Time complexity: O(n)
You can use java Pattern to do it in easy way.
package com.company;
import java.util.regex.Pattern;
public class umeshtest {
public static void main(String a[]) {
String ss = "I'm Testing and testing the new feature";
Pattern.compile(" ").splitAsStream(ss).forEach(s -> System.out.println(s));
}
}
You can also use String.substring or charAt[].

Extract digits from a string in Java

I have a Java String object. I need to extract only digits from it. I'll give an example:
"123-456-789" I want "123456789"
Is there a library function that extracts only digits?
Thanks for the answers. Before I try these I need to know if I have to install any additional llibraries?
You can use regex and delete non-digits.
str = str.replaceAll("\\D+","");
Here's a more verbose solution. Less elegant, but probably faster:
public static String stripNonDigits(
final CharSequence input /* inspired by seh's comment */){
final StringBuilder sb = new StringBuilder(
input.length() /* also inspired by seh's comment */);
for(int i = 0; i < input.length(); i++){
final char c = input.charAt(i);
if(c > 47 && c < 58){
sb.append(c);
}
}
return sb.toString();
}
Test Code:
public static void main(final String[] args){
final String input = "0-123-abc-456-xyz-789";
final String result = stripNonDigits(input);
System.out.println(result);
}
Output:
0123456789
BTW: I did not use Character.isDigit(ch) because it accepts many other chars except 0 - 9.
public String extractDigits(String src) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < src.length(); i++) {
char c = src.charAt(i);
if (Character.isDigit(c)) {
builder.append(c);
}
}
return builder.toString();
}
Using Google Guava:
CharMatcher.inRange('0','9').retainFrom("123-456-789")
UPDATE:
Using Precomputed CharMatcher can further improve performance
CharMatcher ASCII_DIGITS=CharMatcher.inRange('0','9').precomputed();
ASCII_DIGITS.retainFrom("123-456-789");
input.replaceAll("[^0-9?!\\.]","")
This will ignore the decimal points.
eg: if you have an input as 445.3kg the output will be 445.3.
Using Google Guava:
CharMatcher.DIGIT.retainFrom("123-456-789");
CharMatcher is plug-able and quite interesting to use, for instance you can do the following:
String input = "My phone number is 123-456-789!";
String output = CharMatcher.is('-').or(CharMatcher.DIGIT).retainFrom(input);
output == 123-456-789
public class FindDigitFromString
{
public static void main(String[] args)
{
String s=" Hi How Are You 11 ";
String s1=s.replaceAll("[^0-9]+", "");
//*replacing all the value of string except digit by using "[^0-9]+" regex.*
System.out.println(s1);
}
}
Output: 11
Use regular expression to match your requirement.
String num,num1,num2;
String str = "123-456-789";
String regex ="(\\d+)";
Matcher matcher = Pattern.compile( regex ).matcher( str);
while (matcher.find( ))
{
num = matcher.group();
System.out.print(num);
}
I inspired by code Sean Patrick Floyd and little rewrite it for maximum performance i get.
public static String stripNonDigitsV2( CharSequence input ) {
if (input == null)
return null;
if ( input.length() == 0 )
return "";
char[] result = new char[input.length()];
int cursor = 0;
CharBuffer buffer = CharBuffer.wrap( input );
while ( buffer.hasRemaining() ) {
char chr = buffer.get();
if ( chr > 47 && chr < 58 )
result[cursor++] = chr;
}
return new String( result, 0, cursor );
}
i do Performance test to very long String with minimal numbers and result is:
Original code is 25,5% slower
Guava approach is 2.5-3 times slower
Regular expression with D+ is 3-3.5 times slower
Regular expression with only D is 25+ times slower
Btw it depends on how long that string is. With string that contains only 6 number is guava 50% slower and regexp 1 times slower
Using Kotlin and Lambda expressions you can do it like this:
val digitStr = str.filter { it.isDigit() }
You can use str.replaceAll("[^0-9]", "");
I have finalized the code for phone numbers +9 (987) 124124.
Unicode characters occupy 4 bytes.
public static String stripNonDigitsV2( CharSequence input ) {
if (input == null)
return null;
if ( input.length() == 0 )
return "";
char[] result = new char[input.length()];
int cursor = 0;
CharBuffer buffer = CharBuffer.wrap( input );
int i=0;
while ( i< buffer.length() ) { //buffer.hasRemaining()
char chr = buffer.get(i);
if (chr=='u'){
i=i+5;
chr=buffer.get(i);
}
if ( chr > 39 && chr < 58 )
result[cursor++] = chr;
i=i+1;
}
return new String( result, 0, cursor );
}
Code:
public class saasa {
public static void main(String[] args) {
// TODO Auto-generated method stub
String t="123-456-789";
t=t.replaceAll("-", "");
System.out.println(t);
}
import java.util.*;
public class FindDigits{
public static void main(String []args){
FindDigits h=new FindDigits();
h.checkStringIsNumerical();
}
void checkStringIsNumerical(){
String h="hello 123 for the rest of the 98475wt355";
for(int i=0;i<h.length();i++) {
if(h.charAt(i)!=' '){
System.out.println("Is this '"+h.charAt(i)+"' is a digit?:"+Character.isDigit(h.charAt(i)));
}
}
}
void checkStringIsNumerical2(){
String h="hello 123 for 2the rest of the 98475wt355";
for(int i=0;i<h.length();i++) {
char chr=h.charAt(i);
if(chr!=' '){
if(Character.isDigit(chr)){
System.out.print(chr) ;
}
}
}
}
}

Categories