JAVA : String Manipulation using Split function - java

I have a string "AB12TRHW4TR6HH58", i need to split this string and whenever i find a number, i need to perform addition of all. However, if there are consecutive numbers then i need to take it as a whole number.
For example, in above string the addition should be done like 12+4+6+58 and so on.
I written below code which adds all numbers individually but cant take a whole number. Could you please help?
public class TestClass {
public static void main(String[] args) {
String str = "AB12TRHW4TR6HH58";
int len = str.length();
String[] st1 = str.split("");
int temp1=0;
for(int i=0;i<=len-1;i++){
if(st1[i].matches("[0-9]")){
int temp = Integer.parseInt(st1[i]);
temp1 = temp+temp1;
}
}
System.out.println(temp1);
}
}

Doing what I said in my comment:
String str = "AB12TRHW4TR6HH58";
String[] r = str.split("[a-zA-Z]");
int sum = 0;
for ( String s : r ) {
if ( s.length() > 0 ) {
sum += Integer.parseInt(s);
}
}
System.out.println(sum);

You can split on non-numeric characters and use the resulting array:
String[] st1 = "AB12TRHW4TR6HH58".split("[^0-9]+");
int temp1 = 0;
for (int i = 0; i < st1.length; i++) {
if (st1[i].isEmpty()) {
continue;
}
temp1 += Integer.parseInt(st1[i]);
}
System.out.println(temp1);
And it can even be simplified further using a stream:
int temp1 = Stream.of(st1)
.filter(s -> !s.isEmpty())
.mapToInt(Integer::new)
.sum();

Instead of splitting around the parts you want to omit, just search what you need: the numbers. Using a Matcher and Stream we can do this like that:
String str = "AB12TRHW4TR6HH58";
Pattern number = Pattern.compile("\\d+");
int sum = number.matcher(str)
.results()
.mapToInt(r -> Integer.parseInt(r.group()))
.sum();
System.out.println(sum); // 80
Or with an additional mapping but using only method references:
int sum = number.matcher(str)
.results()
.map(MatchResult::group)
.mapToInt(Integer::parseInt)
.sum();

Related

How to sort a array that contains special characters alphabetically?

I am looking for code that produces the following output in standard output from the following string prepared according to a certain format.
Assumptions and rules:
Each letter is used 2 times in the given string and the letters between the same 2 letters are to be considered child letters.
The given string is always given in proper format. The string format
does not need to be checked.
Example:
Input : abccbdeeda
Expected output:
a
--b
----c
--d
----e
Explanation: since the 2 letters "b" occur between the letters "a", the letter b takes 2 hyphens (--b)
Attempt
public static void main(String[] args) {
String input = "abccbdeeda";
System.out.println("input: " + input);
String[] strSplit = input.split("");
String g = "";
String h = "-";
ArrayList<String> list = new ArrayList<String>();
int counter = 1;
boolean secondNumber;
list.add(strSplit[0]);
int dual = 0;
for (int i = 1; i < strSplit.length; i++) {
secondNumber = list.contains(strSplit[i]);
if ((secondNumber)) {
counter--;
dual = counter * 2;
for (int f = 0; f < dual; f++) {
strSplit[i] = h.concat(strSplit[i]);
}
g = "";
dual = 0;
} else {
list.add(strSplit[i]);
counter++;
}
}
Arrays.sort(strSplit);
for (int p = 0; p < strSplit.length; p++) {
System.out.println(strSplit[p]);
}
}
input: abccbdeeda
My output:
----c
----e
--b
--d
a
I wasn't able to sort the output alphabetically. How can I sort alphabetically with those hyphen characters in them?
This task is nicely done with the help of a stack. If the current character is equal to the top of the stack, then the character is closed and can be removed, otherwise we met it for the first time and it must be added to the stack and the resulting string by adding before it stack.size() * 2 dashes.
When we have completely traversed the string we can sort the resulting string.
public static void main(String[] args) {
Stack<Character> stack = new Stack<>();
String string = "abccbdeeda";
StringBuilder result = new StringBuilder();
for(int i = 0; i < string.length(); i++) {
char curChar = string.charAt(i);
if(!stack.isEmpty() && curChar == stack.peek()) {
stack.pop();
} else {
result.append("-".repeat(stack.size() * 2)).append(curChar).append(" ");
stack.add(curChar);
}
}
System.out.println(result);
System.out.println(Arrays.toString(Arrays.stream(result.toString().split(" ")).sorted().toArray()));
}
Output
a --b ----c --d ----e
[----c, ----e, --b, --d, a]
You can go through the strSplit array and extract the charactors in each element to a separate list/array. To check whether the array element contains a letter you can write a regular expression.
Ex: private final Pattern x = Pattern.compile("[a-z]");
Write a separate method to match the patern to each element in the strSplit array. This method will return the charactor in your input string.
private String findCharactor(final StringBuilder element) {
final Matcher matcher = x.matcher(element);
if (matcher.find()) {
final int matchIndex = matcher.start(); //this gives the index of the char in the string
return element.substring(matchIndex);
}
}
Add these returned charactors to a separate array and sort it using sorting function.
Suppose your result list is:
List<String> resultList = Arrays.asList("----c", "----e", "--b", "--d", "a");
You can sort it alphabetically by a single line:
Collections.sort(resultList, (o1, o2) -> new StringBuilder(o1).reverse().toString().compareTo(new StringBuilder(o2).reverse().toString()));
You can use recursion for a depth-first traversal (preorder):
public static String dfs(String string, String prefix) {
if (string.length() == 0) return "";
int i = string.indexOf(string.charAt(0), 1);
return prefix + string.charAt(0) + "\n" // current
+ dfs(string.substring(1, i), prefix + "--") // all nested
+ dfs(string.substring(i + 1), prefix); // all siblings
}
Example call:
public static void main(String[] args) {
System.out.println(dfs("abccbdeeda", ""));
}

Finding Count of Pattern in a String (Overlap Inclusive)

So I'm trying to write an algorithm that counts the number of occurrences of some pattern, say "aa", within a string, say "aaabca." The number of patterns in that string should return an integer, in this case 2, because the first three characters contain two occurrences of the pattern.
What I have finds the number of patterns under the assumption the existing occurrences of a pattern is NOT overlapping:
public class Pattern{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
System.out.println("Enter the string: ");
String s = scan.nextLine();
String[] splittedInput = s.split(";");
String pattern = splittedInput[0];
String blobs = splittedInput[1];
Pattern p = new Pattern();
p.count(pattern, blobs);
}
public static void count(String pattern, String blobs){
String[] substrings = blobs.split("[|]");
int numOccurences = 0;
int[] instances = new int[substrings.length];
int patternLength = pattern.length();
for (int i = 0; i < instances.length; i++){
int length = substrings[i].length();
String temp = substrings[i];
temp = temp.replaceAll(pattern, "");
int postLength = temp.length();
numOccurences = (length - postLength) / pattern.length();
instances[i] = numOccurences;
numOccurences = 0;
}
int sum = 0;
for (int i = 0; i < instances.length; i++){
System.out.print(instances[i] + "|");
sum += instances[i];
}
System.out.print(sum);
}
}
Any suggestions?
I would personally compare the pattern as a substring in this case. For example a run of a single String from your array would look like this:
//Initial values
String blobs = "aaaabcaaa";
String pattern = "aab";
String[] substrings = blobs.split("[|]");
//The code I added that should placed into the loop
int numOccurences = 0;
String str = substrings[0];
for (int k = 0; k <= (str.length() - pattern.length()); k++)
{
if (str.substring(k, k + pattern.length()).equals(pattern))
{
numOccurences++;
}
}
System.out.println(numOccurences);
If you want to run this on each String in your array simply modify String str = substrings[0] to String str = substrings[i] and iterate over the array storing the final numOccurences as you please.
Example Run:
String is aaaabcaaa
Pattern is aa
Output is 5 occurences
For one String, match is the String you're looking for:
int len = theStr.length ();
int start = 0;
int pos;
int count = 0;
while ((start < len) && ((pos = theStr.indexOf (match, start)) >= 0))
{
++count;
start = pos + 1;
}
If you use Java 8 you can count this value in the following way.
Example:
String blobs = "aaabcaaa";
String pattern = "aa";
List<String> strings = Arrays.asList(blobs.split(""));
long count = IntStream.range(0, strings.size())
.mapToObj(index -> index < strings.size() - 1 ? strings.get(index) + strings.get(index + 1) : strings.get(index - 1))
.filter(str -> str.equals(pattern))
.count();
System.out.println("Result count: " + count);
Continually taking substrings and using the startsWith method seems to work pretty well.
String pat = "ss";
String str = "kskslsksaaaslsslssskssssllsssss";
int count = 0;
while (str.length() >= pat.length()) {
count += str.startsWith(pat) ? 1 : 0;
str = str.substring(1);
}
System.out.println("count = " + count);
You can also take a similar approach with streams.
long count = IntStream.range(0, str.length()).mapToObj(
n -> str.substring(n)).filter(n -> n.startsWith(pat)).count();
System.out.println("count = " + count);
But in this case I actually prefer the non-stream approach.

How to split string at every nth occurrence of character in Java

I would like to split a string at every 4th occurrence of a comma ,.
How to do this? Below is an example:
String str = "1,,,,,2,3,,1,,3,,";
Expected output:
array[0]: 1,,,,
array[1]: ,2,3,,
array[2]: 1,,3,,
I tried using Google Guava like this:
Iterable<String> splitdata = Splitter.fixedLength(4).split(str);
output: [1,,,, ,,2,, 3,,1, ,,3,, ,]
I also tried this:
String [] splitdata = str.split("(?<=\\G.{" + 4 + "})");
output: [1,,,, ,,2,, 3,,1, ,,3,, ,]
Yet this is is not the output I want. I just want to split the string at every 4th occurrence of a comma.
Thanks.
Take two int variable. One is to count the no of ','. If ',' occurs then the count will move. And if the count is go to 4 then reset it to 0. The other int value will indicate that from where the string will be cut off. it will start from 0 and after the first string will be detected the the end point (char position in string) will be the first point of the next. Use the this start point and current end point (i+1 because after the occurrence happen the i value will be incremented). Finally add the string in the array list. This is a sample code. Hope this will help you. Sorry for my bad English.
String str = "1,,,,,2,3,,1,,3,,";
int k = 0;
int startPoint = 0;
ArrayList<String> arrayList = new ArrayList<>();
for (int i = 0; i < str.length(); i++)
{
if (str.charAt(i) == ',')
{
k++;
if (k == 4)
{
String ab = str.substring(startPoint, i+1);
System.out.println(ab);
arrayList.add(ab);
startPoint = i+1;
k = 0;
}
}
}
Here's a more flexible function, using an idea from this answer:
static List<String> splitAtNthOccurrence(String input, int n, String delimiter) {
List<String> pieces = new ArrayList<>();
// *? is the reluctant quantifier
String regex = Strings.repeat(".*?" + delimiter, n);
Matcher matcher = Pattern.compile(regex).matcher(input);
int lastEndOfMatch = -1;
while (matcher.find()) {
pieces.add(matcher.group());
lastEndOfMatch = matcher.end();
}
if (lastEndOfMatch != -1) {
pieces.add(input.substring(lastEndOfMatch));
}
return pieces;
}
This is how you call it using your example:
String input = "1,,,,,2,3,,1,,3,,";
List<String> pieces = splitAtNthOccurrence(input, 4, ",");
pieces.forEach(System.out::println);
// Output:
// 1,,,,
// ,2,3,,
// 1,,3,,
I use Strings.repeat from Guava.
try this also, if you want result in array
String str = "1,,,,,2,3,,1,,3,,";
System.out.println(str);
char c[] = str.toCharArray();
int ptnCnt = 0;
for (char d : c) {
if(d==',')
ptnCnt++;
}
String result[] = new String[ptnCnt/4];
int i=-1;
int beginIndex = 0;
int cnt=0,loopcount=0;
for (char ele : c) {
loopcount++;
if(ele==',')
cnt++;
if(cnt==4){
cnt=0;
result[++i]=str.substring(beginIndex,loopcount);
beginIndex=loopcount;
}
}
for (String string : result) {
System.out.println(string);
}
This work pefectly and tested in Java 8
public String[] split(String input,int at){
String[] out = new String[2];
String p = String.format("((?:[^/]*/){%s}[^/]*)/(.*)",at);
Pattern pat = Pattern.compile(p);
Matcher matcher = pat.matcher(input);
if (matcher.matches()) {
out[0] = matcher.group(1);// left
out[1] = matcher.group(2);// right
}
return out;
}
//Ex: D:/folder1/folder2/folder3/file1.txt
//if at = 2, group(1) = D:/folder1/folder2 and group(2) = folder3/file1.txt
The accepted solution above by Saqib Rezwan does not add the leftover string to the list, if it divides the string after every 4th comma and the length of the string is 9 then it will leave the 9th character, and return the wrong list.
A complete solution would be :
private static ArrayList<String> splitStringAtNthOccurrence(String str, int n) {
int k = 0;
int startPoint = 0;
ArrayList<String> list = new ArrayList();
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == ',') {
k++;
if (k == n) {
String ab = str.substring(startPoint, i + 1);
list.add(ab);
startPoint = i + 1;
k = 0;
}
}
// if there is no comma left and there are still some character in the string
// add them to list
else if (!str.substring(i).contains(",")) {
list.add(str.substring(startPoint));
break;
}
}
return list;
}
}

java program to return the sum of all integers found in the parameter String

i want write a java program to return the sum of all integers found in the parameter String.
for example take a string like:" 12 hi when 8 and 9"
now the answer is 12+8+9=29.
but i really dont know even how to start can any one help in this!
You may start with replacing all non-numbers from the string with space, and spilt it based on the space
String str = "12 hi when 8 and 9";
str=str.replaceAll("[\\D]+"," ");
String[] numbers=str.split(" ");
int sum = 0;
for(int i=0;i<numbers.length;i++){
try{
sum+=Integer.parseInt(numbers[i]);
}
catch( Exception e ) {
//Just in case, the element in the array is not parse-able into Integer, Ignore it
}
}
System.out.println("The sum is:"+sum);
You shall use Scanner to read your string
Scanner s = new Scanner(your string);
And then read it using
s.nextInt();
Then add these integers.
Here is the general algorithm:
Initialize your sum to zero.
Split the string by spaces, and for each token:
Try to convert the token into an integer.
If no exception is thrown, then add the integer to your sum.
And here is a coding example:
int sumString(String input)
{
int output = 0;
for (String token : input.split(" "))
{
try
{
output += Integer.parseInt(token);
}
catch (Exception error)
{
}
}
return output;
}
private static int getSumOfIntegersInString(String string) {
/*Split the String*/
String[] stringArray = string.split(" ");
int sum=0;
int temp=0;
for(int i=0;i<stringArray.length;i++){
try{
/*Convert the numbers in string to int*/
temp = Integer.parseInt(stringArray[i]);
sum += temp;
}catch(Exception e){
/*ignore*/
}
}
return sum;
}
You could use a regular expression
Pattern p = Pattern.compile("\\d+");
String s = " 12 hi when 8 and 9" ;
Matcher m = p.matcher(s);
int start = 0;
int sum=0;
while(m.find(start)) {
String n = m.group();
sum += Integer.parseInt(n);
start = m.end();
}
System.out.println(sum);
This approach does not require the items to be separated by spaces so it would work with "12hiwhen8and9".
Assume your words are separated by whitespace(s):
Then split your input string into "tokens"(continuous characters without whitespace).
And then loop them, try to convert each of them into integer, if exception thrown, means this token doesn't represents a integer.
Code:
public static int summary(String s) {
String[] tokens = s.split("\\s+");
int sum = 0;
for(String token : tokens) {
try {
int val = Integer.parseInt(token);
sum += val;
}
catch(NumberFormatException ne){
// Do nothing
}
}
return sum;
}
String s ="12 hi when 8 and 9";
s=s.replaceAll("[^0-9]+", " ");
String[] numbersArray= s.split(" ");
Integer sum = 0;
for(int i = 0 ; i<numbersArray.length;i++){
if(numbersArray[i].trim().length() != 0){
Integer value = Integer.valueOf(numbersArray[i].trim());
sum = sum + value;
}
}
System.out.println(sum);
You can have a look on the following code :-
public class Class02
{
public static void main(String[] args)
{
String str = "12 hi when 8 and 9";
int sum = 0;
List<String> list = new ArrayList<String>();
StringTokenizer st = new StringTokenizer(str.toLowerCase());
while(st.hasMoreElements())
{
list.add(st.nextToken());
}
for(int i =0; i< list.size();i++)
{
char [] array = list.get(i).toCharArray();
int num = array[0];
if(!(num >= 'a' && num <= 'z'))
{
int number = Integer.valueOf((list.get(i).toString()));
sum = sum + number;
}
}
System.out.println(sum);
}
}
Hope it will help you.
I understand that this does not have the Java8 tag but I will put this out there in case someone finds it interesting
String str = "12 hi when 8 and 9";
System.out.println(Arrays.stream(str.split(" "))
.filter(s -> s.matches("[0-9]+")).mapToInt(Integer::parseInt).sum());
would nicely print out 29

how to extract numeric values from input string in java

How can I extract only the numeric values from the input string?
For example, the input string may be like this:
String str="abc d 1234567890pqr 54897";
I want the numeric values only i.e, "1234567890" and "54897". All the alphabetic and special characters will be discarded.
You could use the .nextInt() method from the Scanner class:
Scans the next token of the input as an int.
Alternatively, you could also do something like so:
String str=" abc d 1234567890pqr 54897";
Pattern p = Pattern.compile("(\\d+)");
Matcher m = p.matcher(str);
while(m.find())
{
System.out.println(m.group(1));
}
String str=" abc d 1234567890pqr 54897";
Pattern pattern = Pattern.compile("\\w+([0-9]+)\\w+([0-9]+)");
Matcher matcher = pattern.matcher(str);
for(int i = 0 ; i < matcher.groupCount(); i++) {
matcher.find();
System.out.println(matcher.group());
}
Split your string into char array using yourString.toCharArray(); Then iterate through the characters and use Character.isDigit(ch); to identify if this is the numeric value. Or iterate through whole string and use str.charAt(i). For e.g:
public static void main(String[] args) {
String str = "abc d 1234567890pqr 54897";
StringBuilder myNumbers = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
if (Character.isDigit(str.charAt(i))) {
myNumbers.append(str.charAt(i));
System.out.println(str.charAt(i) + " is a digit.");
} else {
System.out.println(str.charAt(i) + " not a digit.");
}
}
System.out.println("Your numbers: " + myNumbers.toString());
}
You could do something like:
Matcher m = Pattern.compile("\\d+").matcher(str);
while (m.find()) {
System.out.println(m.group(0));
}
You can use str = str.replaceAll("replaced_string","replacing_string");
String str=" abc d 1234567890pqr 54897";
String str_rep1=" abc d ";
String str_rep2="pqr ";
String result1=str.replaceAll("", str_rep1);
String result2=str.replaceAll(",",str_rep2);
also what npinti suggests is fine to work with.
Example using java Scanner class
import java.util.Scanner;
Scanner s = new Scanner( "abc d 1234567890pqr 54897" );
s.useDelimiter( "\\D+" );
while ( s.hasNextInt() ){
s.nextInt(); // get int
}
If you do not want to use regex,
String str = " abc d 1234567890pqr 54897";
char[] chars = new char[str.length()];
int i = 0;
for (int j = 0; j < str.length(); j++) {
char c = str.charAt(j);
if (Character.isDigit(c)) {
chars[i++] = c;
if (j != chars.length - 1)
continue;
}
if (chars[0] == '\0')
continue;
String num = new String(chars).trim();
System.out.println(num);
chars = new char[str.length()];
i = 0;
}
Output :
1234567890
54897
String line = "This order was32354 placed 343434for 43411 QT ! OK?";
String regex = "[^\\d]+";
String[] str = line.split(regex);
String required = "";
for(String st: str){
System.out.println(st);
}
By above code you will get all the numeric values. then you can merge them or what ever you wanted to do with those numeric values.
You want to discard everything except digits and spaces:
String nums = input.replaceAll("[^0-9 ]", "").replaceAll(" +", " ").trim();
The extra calls clean up doubled and leading/trailing spaces.
If you need an array, add a split:
String[] nums = input.replaceAll("[^0-9 ]", "").trim().split(" +");
You could split the string on spaces to get the individual entries, loop across them, and try to parse them with the relevant method on Integer, using a try/catch approach to handle the cases where parsing it is as a number fails. That is probably the most straight-forward approach.
Alternatively, you can construct a regex to match only the numbers and use that to find them all. This is probably far more performant for a big string. The regex will look something like `\b\d+\b'.
UPDATE: Or, if this isn't homework or similar (I sort of assumed you were looking for clues to implementing it yourself, but that might not have been valid), you could use the solution that #npinti gives. That's probably the approach you should take in production code.
public static List<String> extractNumbers(String string) {
List<String> numbers = new LinkedList<String>();
char[] array = string.toCharArray();
Stack<Character> stack = new Stack<Character>();
for (int i = 0; i < array.length; i++) {
if (Character.isDigit(array[i])) {
stack.push(array[i]);
} else if (!stack.isEmpty()) {
String number = getStackContent(stack);
stack.clear();
numbers.add(number);
}
}
if(!stack.isEmpty()){
String number = getStackContent(stack);
numbers.add(number);
}
return numbers;
}
private static String getStackContent(Stack<Character> stack) {
StringBuilder sb = new StringBuilder();
Enumeration<Character> elements = stack.elements();
while (elements.hasMoreElements()) {
sb.append(elements.nextElement());
}
return sb.toString();
}
public static void main(String[] args) {
String str = " abc d 1234567890pqr 54897";
List<String> extractNumbers = extractNumbers(str);
for (String number : extractNumbers) {
System.out.println(number);
}
}
Just extract the digits
String str=" abc d 1234567890pqr 54897";
for(int i=0; i<str.length(); i++)
if( str.charAt(i) > 47 && str.charAt(i) < 58)
System.out.print(str.charAt(i));
Another version
String str=" abc d 1234567890pqr 54897";
boolean flag = false;
for(int i=0; i<str.length(); i++)
if( str.charAt(i) > 47 && str.charAt(i) < 58) {
System.out.print(str.charAt(i));
flag = true;
} else {
System.out.print( flag ? '\n' : "");
flag = false;
}
public class ExtractNum
{
public static void main(String args[])
{
String input = "abc d 1234567890pqr 54897";
String digits = input.replaceAll("[^0-9.]","");
System.out.println("\nGiven Number is :"+digits);
}
}
public static String convertBudgetStringToPriceInteger(String budget) {
if (!AndroidUtils.isEmpty(budget) && !"0".equalsIgnoreCase(budget)) {
double numbers = getNumericFromString(budget);
if( budget.contains("Crore") ){
numbers= numbers* 10000000;
}else if(budget.contains("Lac")){
numbers= numbers* 100000;
}
return removeTrailingZeroesFromDouble(numbers);
}else{
return "0";
}
}
Get numeric value from alphanumeric string
public static double getNumericFromString(String string){
try {
if(!AndroidUtils.isEmpty(string)){
String commaRemovedString = string.replaceAll(",","");
return Double.parseDouble(commaRemovedString.replaceAll("[A-z]+$", ""));
/*return Double.parseDouble(string.replaceAll("[^[0-9]+[.[0-9]]*]", "").trim());*/
}
}catch (NumberFormatException e){
e.printStackTrace();
}
return 0;
}
For eg . If i pass 1.5 lac or 15,0000 or 15 Crores then we can get numeric value from these fucntion . We can customize string according to our needs.
For eg. Result would be 150000 in case of 1.5 Lac
String str = "abc d 1234567890pqr 54897";
str = str.replaceAll("[^\\d ]", "");
The result will be "1234567890 54897".
String str = "abc34bfg 56tyu";
str = str.replaceAll("[^0-9]","");
output: 3456

Categories

Resources