I have a string which looks something like this(the most basic form):
String str = "1.0.0.190"
The str can be something like this as well:
1.11.0.12 or 2.111.1.190 or 1.0.0.0
I want to split the string at the 2nd occurrence of the dot(.). How can I achieve that ?
Output:
String str = "1.0.0.190"
String output = "1.0"
I'd fit the answer to OP's level, so I wouldn't recommend split or regexps to him...
If you need substring to second dot, simply find second dot and cut the string to that position...
public class DotSubstring {
public static void main(String[] args) {
String s = "1.2.3.4";
int secondDotPosition = findSecondDotPosition(s);
if (secondDotPosition > 0) {
System.out.println(s.substring(0, secondDotPosition));
} else {
System.out.printf("ERROR: there is not a 2nd dot in '%s'%n", s);
}
}
private static int findSecondDotPosition(String s) {
int result = -1;
int dotsToFind = 2;
char[] ca = s.toCharArray();
for (int i = 0; i < ca.length; ++i) {
if (ca[i] == '.') --dotsToFind;
if (dotsToFind == 0) return i;
}
return result;
}
}
The problem with split for beginner is, that is accepts regexp, that's why it is escaped in Joop Eggen's answe like this str.split("\\.").
And yes, that can be achieved in one line as user3458271 wrote in a comment same as xyz later in answer, just error checking would be more difficult (for example if there are no 2 dots...).
In one line with substring and indexOf:
String output = str.substring(0,str.indexOf(".",str.indexOf(".")+1));
public static void main(String[] args) {
String input = "2.111.1.190";
String[] out = input.split("\\.");
String output1 = out[0]+"."+out[1];
System.out.println(output1);
String output2 = "";
for(int x=2; x < out.length; x++)
output2 += out[x] +".";
System.out.println(output2);
}
For the other fields too:
String[] halfs = str.split("\\.");
String[] fulls = new String[halfs.length / 2];
for (int i = 0; i < fulls.length; ++i) {
fulls[i] = halfs[2*i] + "." + halfs[2*i + 1];
}
return fulls[0];
The same technique reduced for the first field:
String[] halfs = str.split("\\.", 3);
return halfs[0] + "." + halfs[1];
Simply:
return str.replaceAll("^([^.]*\\.[^.]*)\\..*$", "$1");
Related
I try to create a function that changes the String from StackOverflow is the best. to best. the is StackOverflow.
I wrote the following function, but can't seem to fix the spaces in the result string. For some reason, I receive best.the is Stackoverflow. There is no space between best. & the, and there is an extra space after StackOverflow.
I could add a variable that represents space and use if's in the edge cases, but I believe that there is a better way to do so.
Could anyone help me figure this out?
public static void main(String[] args) {
String str = "Stackoverflow is the best.";
String result = change(str);
System.out.println(result);
}
private static String change(String str) {
String result = "";
int i1 = str.length()-1;
int i2 = str.length();
for (i1 = str.length(); i1 >= 0; i1--) {
if (i1 ==0 || str.charAt(i1-1) == ' ') {
result = result.concat(str.substring(i1, i2));
i2 = i1;
}
}
return result;
}
One way i could think of without using if's is :
String line = "Stackoverflow is the best.";
String delimeter = " ";
final String[] words = line.split(delimeter);
String reversedLine = "";
for(int i = words.length - 1; i >= 0; i--) {
reversedLine += words[i] + delimeter;
}
// remove the delimeter present at last of line
reversedLine = reversedLine.substring(0, reversedLine.length() - 1);
System.out.println(reversedLine);
To generate the output as you have mentioned, I would approach a problem in this way:
class Solution {
public static void main(String[] args) {
String str = "StackOverflow is the best.";
String[] arr = str.split(" ");
System.out.print(arr[arr.length-1]);
for(int i = arr.length - 2; i >= 0; i--){
System.out.print(" "+arr[i]);
}
}
}
The only reason to your problem is that you haven't added the space after the '.'
Try using String str = "Stackoverflow is the best. ";
Hope it helped... :)
I have this number: 4200000000000000
I would like to leave only the first 4 digits and last 3 digits:
42000......000
Everything else should be replaced by dots. How I can implement this with some smart algorithm?
Why not use a StringBuilder and the substring method:
public static String foo(long num) {
String numToString = String.valueOf(num);
return new StringBuilder()
.append(numToString.substring(0 , 4))
.append("....")
.append(numToString.substring(numToString.length()-3, numToString.length()))
.toString();
}
When inputted 4200000000000000 it outputs:
4200....000
Or if the input is already a String:
public static String foo(String str) {
return new StringBuilder()
.append(str.substring(0 , 4))
.append("....")
.append(str.substring(str.length()-3, str.length()))
.toString();
}
Parse your number into a string and try this:
int last = 3;
int first = 4;
String number = '4200000000000000';
String start = number.substring(0,first-1);
String end = number.substring(number.length()-last,number.length()-1);
String dots = '';
for(int i = 0; i<number.length()-last-first;i++){
dots = dots + '.';
}
String result = start + dots + end;
You can use something like this,
public class Main {
public static void main(String[] args) {
System.out.println(convert("4200000000000000", 4, 3));
}
static String convert(String number, int firstDigits, int lastDigits) {
String first = number.substring(0, firstDigits);
String middle = number.substring(firstDigits, number.length() - lastDigits).replaceAll("0", ".");
String last = number.substring(number.length() - lastDigits, number.length());
return first + middle + last;
}
}
You could convert it to a char array, alter it, then convert it back into a string
char[] charArray = originalNumber.toCharArray();
for (int i; i < charArray.length; i++) {
if (i <= 4 || i >= charArray.length - 3) {
charArray[i] = ".";
}
}
String outputString = new String(charArray);
This will replace all chars from the 4th char up to the 4th from the end with '.':
String start = "4200000000000000";
System.out.println(start);
String target = start;
if (start.length() > 7) {
target = new StringBuilder()
.append(start.substring(0, 4))
.append(new String(new char[start.length() - 7]).replaceAll(".", "."))
.append(start.substring(start.length() - 3))
.toString();
}
System.out.println(target);
will print
4200000000000000
4200.........000
Using substring method of the String class :
String str = "4200000000000000";
String res = str.substring(0,4)+ str.substring(4,str.length()-3).replaceAll(".", ".") + str.substring(str.length()-3);
If you are using Apache commons library, you can use repeat method to create masking string of specified length and the overlay method of StringUtils class to overlay part of the String :
String str = "4200000000000000";
String mask= StringUtils.repeat('.', str.length()-7);
String res = StringUtils.overlay(str, mask, 4, str.length()-3);
Lets say I have a string "aabbccaa". Now I want to replace occurrences of "aa" in given string by another string. But it should be in following way.
First occurrence of "aa" should be replaced by "1" and next occurrence of "aa" by "2" and so on.
So, the result of the string becomes "1bbcc2".
You can use replaceFirst() in a for loop where counter is incrementing...
for (int i = 1; string.contains("aa"); i++) {
string = string.replaceFirst("aa", "" + i);
}
You can do it using the Matcher's appendReplacement method:
Pattern p = Pattern.compile("aa");
Matcher m = p.matcher("aabbccaahhhaahhhaaahahhahaaakty");
StringBuffer sb = new StringBuffer();
// Variable "i" serves as a counter. It gets incremented after each replacement.
int i = 0;
while (m.find()) {
m.appendReplacement(sb, ""+(i++));
}
m.appendTail(sb);
System.out.println(sb.toString());
This approach lets you avoid creating multiple string objects (demo).
It is possible to do using Java functions but using a char array and doing it using a lower level of logic would be faster.
String s = "aabbccaa";
String target = "aa";
int i = 1;
String newS;
for (int j = 0; j < s.length; j++) {
newS = s.replaceFirst(target, i++);
j += newS.length - s.length;
s = newS;
}
Here is a solution :
public static void main(String[] a) {
int i = 1;
String before = "aabbccaabbaabbaa";
String regex = "aa";
String after = substitute(i, before, regex);
System.out.println(after);
}
private static String substitute(int i, String before, String regex) {
String after = before.replaceFirst(regex, Integer.toString(i++));
while (!before.equals(after)) {
before = after;
after = before.replaceFirst(regex, Integer.toString(i++));
}
return after;
}
Output :
1bbcc2bb3bb4
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;
}
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[].