Jstl: format string number with spaces - java

I am looking for an implementation of the following:
I have a string: 001001001
And I need to receive at the output: 001 001 001
I checked the formatNumber and DecimalFormat - they can not provide such kind of output.
Is there any other built-in methods?
Currently I created some server-side function (that is actually not so brilliant solution I think):
StringBuffer result = new StringBuffer("");
for (int i = 1; i <= 9; i++) {
result.append(input.charAt(i - 1));
if (i % 3 == 0)
result.append(" ");
}
return result.toString();

I use the method below.
Does not add extra space at the end like in the example from nKognito.
public static String format(String inputUnformatted, int groupSize, String separator) {
StringBuilder result = new StringBuilder(inputUnformatted);
int i = groupSize;
while (i < inputUnformatted.length()) {
result.insert(inputUnformatted.length() - i, separator);
i += groupSize;
}
return result.toString();
}

public static void main(String[] args) {
String input = "001001001";
StringBuilder result = new StringBuilder();
int j = 0;
for (int i = 0; i < input.length(); i++) {
if (j > 2) {
result.append(" ");
j = 0;
}
result.append(input.charAt(i));
j++;
}
System.out.println(result.toString());
}
try this piece of code

Related

Modifying String in Java

I have a String , String a = newNumber + "*" + nn + "+" + difference;
the newNumber = 106 , nn = 3 and difference = 3.
so the output should be as follow ;
Output :
106*3+3
I would like to modify the String so that the output becomes (35*3+1)*3+3 and then with this new String I would like to modify it again so that it becomes ((11*3+2)*3+1)*3+3
Basically I just need to replace the newNumber which was 106 and kept changing to 11, as you can see I'm trying to modify only the newNumber and replacing it with another while keeping the entire String untouched , I'm just replacing and adding to it , how can this be achieved ?
The output should be like this,
Output :
106*3+3
(35*3+1)*3+3
((11*3+2)*3+1)*3+3
I'm solving an equation with steps , the formulas don't matter I'm just trying to figure out how can I modify the String by replacing the newNumber with a another number and adding new brackets to the equation.
I hope I wrote my problem in a way you would understand , I'd really appreciate the help.
I could not get to the same output which you have but here the code which try to solve this problem I think it might give you little help though which you could solve the problem.
Breaking the number until its prime number and adding the prime numbers to the result. Since we are replacing and appending with strings its better to use StringBuilder.
import java.io.PrintStream;
import java.util.Arrays;
public class StringSimplification {
public static PrintStream out = System.out;
public static final boolean prime[];
public static final int SIZE = 1000000;
static {
prime = new boolean[SIZE];
Arrays.fill(prime, true);
prime[0] = prime[1] = false;
//Sieve of Eratosthenes algorithm to find weather number is prime
for (int i = 2; i < SIZE; i++)
if (prime[i])
for (int j = i * 2; j < SIZE; j += i)
prime[j] = false;
}
//simplifies your String expression
public static String simplify(final String expression) {
StringBuilder result = new StringBuilder("");
String exp = "";
for (char ch : expression.toCharArray()) {
if (Character.isDigit(ch))
exp += ch;
else {
if (isNumber(exp)) {
String simplified = getExpression(Integer.parseInt(exp));
result.append(simplified+ch);
exp = "";//clearing exp
};
}
}
result.append(exp);
return result.toString();
}
//returns weather number is prime or not
static boolean isPrime(final int val) {
return prime[val];
}
static String getExpression(final int val) {
if (val == 0 || val == 1 || prime[val])
return "(" + val + ")";
int prev = 1;
int div = 1;
for (int i = 1; i < val; i++) {
if (val % i == 0) {
prev = i;
div = val / i;
}
}
return getExpression(prev) + "*" + getExpression(div);
}
//Check's weather the expression is number
public static boolean isNumber(final String s) {
for (var c : s.toCharArray())
if (!Character.isDigit(c))
return false;
return s.length() > 0;
}
public static void main(final String... $) {
out.println(simplify("106*3+3"));
out.println(simplify("1024*3+3"));
}
}
Output:
(53)*(2)*(3)+3
(2)*(2)*(2)*(2)*(2)*(2)*(2)*(2)*(2)*(2)*(3)+3
You can’t actually modify Strings, but you can use replaceFirst() like this:
s = s.replaceFirst("106", "(35*3+1)");
s = s.replaceFirst("35", "(11*3+2)");
etc
Strings in java are immutable. You will have to use StringBuilder or String Buffer
However if you insist then you may try(from what I understood of the pattern)
int num = 106;
String rep = "";
String S = "106*3+3";
String target;
int b = 1;
int largestfactor = 1;
System.out.println(S);
for (int i = num; i > 0; i--) {
for (int j = 1; j < (num - b); j++) {
if ((num - b) % j == 0)
largestfactor = j;
}
target = "" + num;
rep = "(" + largestfactor + "*" + (num - b) / largestfactor + ")" + "+" + b;
S = S.replace(target,rep);
System.out.println(S);
num = largestfactor;
b++;
if(b>num)
break;
}

Replacing the number with the number of spaces

I have a String:
String example = "AA5DD2EE3MM";
I want to replace the number with the number of spaces. Example:
String example = "AA DD EE MM"
If the String would be
String anotherExample = "a3ee"
It should turn into:
String anotherExample = "a ee"
I want to do it for any string. Not only for the examples above.
Split your input at digit and non digit chars as a stream, map digits to the corsponding number of spaces using String.repeat, collect to string using Collectors.joining():
String input = "AA5DD2EE3MM";
String regex = "(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)";
String result = Pattern.compile(regex)
.splitAsStream(input)
.map(s -> s.matches("\\d+") ? " ".repeat(Integer.parseInt(s)) : s)
.collect(Collectors.joining());
You could also use this approach, which is simpler but also far less elegant:
String example = "a4aa";
String newString = "";
for (int i = 0; i < example.length(); i++) {
if (Character.isDigit(example.charAt(i))) {
for (int a = 0; a < Character.getNumericValue(example.charAt(i)); a++) {
newString += " ";
}
} else {
newString += example.charAt(i);
}
}
System.out.println(newString);
Using a pattern matcher approach:
String input = "AA5DD2EE3MM";
Pattern pattern = Pattern.compile("\\d+");
Matcher m = pattern.matcher(input);
StringBuffer buffer = new StringBuffer();
while (m.find()) {
m.appendReplacement(buffer,new String(new char[Integer.valueOf(m.group())]).replace("\0", " "));
}
m.appendTail(buffer);
System.out.println(buffer.toString()); // AA DD EE MM
The idea here is to iterate the string, pausing at each digit match. We replace each digit with space replicated the same number of times as the digit.
public static String replaceDigitsWithSpaces(String input) {
String result = "";
int len = input.length(), i =0;
while( i < len) {
if(Character.isLetter(input.charAt(i))) {
result += input.charAt(i);
}else if(Character.isDigit(input.charAt(i))) {
//generate number upto characters
int k = 0, j = i;
String temp = "";
while(j < len) {
if(Character.isDigit(input.charAt(j))) {
temp += input.charAt(j);
j++;
}else {
break;
}
}
k = Integer.parseInt(temp);
while(k != 0) {
result+= " ";
k--;
}
i = j;
continue;
}
i++;
}
return result;
}
input:: "AA23BB1C11C8"<br>
output:: AA BB C C .
StringBuilder is more efficient for concatenation:
public static String spaceIt(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isDigit(c)) {
for (int j = 0; j < Character.digit(c, 10); j++) {
sb.append(' ');
}
} else {
sb.append(c);
}
}
return sb.toString();
}

Removing characters from string efficiently

This may sound like a very simple question but how do you remove multiple different characters from a string without having to write a line for each, which is what I have laboriously done. I have written a string example below:
String word = "Hello, t-his is; an- (example) line."
word = word.replace(",", "");
word = word.replace(".", "");
word = word.replace(";", "");
word = word.replace("-", "");
word = word.replace("(", "");
word = word.replace(")", "");
System.out.println(word);
Which would produce "Hello this is an example line". A more efficient way is?
Use
word = word.replaceAll("[,.;\\-()]", "");
Note that special character - (hyphen) should be escaped by double backslashes, because otherwise it is considered to construct a range.
Although no more efficient than the original replace technique you could use
word = word.replaceAll("\\p{Punct}+", "");
to use a simple expression using replaceAll with a wider range of characters replaced
Without (ab)using regex, I would do that way:
String word = "Hello, t-his is; an- (example) line.";
String undesirable = ",.;-()";
int len1 = undesirable.length();
int len2 = word.length();
StringBuilder sb = new StringBuilder(len2);
outer: for (int j = 0; j < len2; j++) {
char c = word.charAt(j);
for (int i = 0; i < len; i++) {
if (c == undesirable.charAt(i)) continue outer;
}
sb.append(c);
}
System.out.println(sb.toString());
The advantage is performance. You don't need the overhead of creating and parsing a regular expression.
You could encapsulate that in a method:
public static String removeCharacters(String word, String undesirable) {
int len1 = undesirable.length();
int len2 = word.length();
StringBuilder sb = new StringBuilder(len2);
outer: for (int j = 0; j < len2; j++) {
char c = word.charAt(j);
for (int i = 0; i < len1; i++) {
if (c == undesirable.charAt(i)) continue outer;
}
sb.append(c);
}
return sb.toString();
}
public static String removeSpecialCharacters(String word) {
return removeCharacters(word, ",.;-()");
}
And then, you would use it this way:
public static void testMethod() {
String word = "Hello, t-his is; an- (example) line.";
System.out.println(removeSpecialCharacters(word));
}
Here is a performance test:
public class WordTest {
public static void main(String[] args) {
int iterations = 10000000;
long t1 = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
testAsArray();
}
long t2 = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
testRegex();
}
long t3 = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
testAsString();
}
long t4 = System.currentTimeMillis();
System.out.println("Without regex, but using copied arrays: " + (t2 - t1));
System.out.println("With precompiled regex: " + (t3 - t2));
System.out.println("Without regex, but using string: " + (t4 - t3));
}
public static void testAsArray() {
String word = "Hello, t-his is; an- (example) line.";
char[] undesirable = ",.;-()".toCharArray();
StringBuilder sb = new StringBuilder(word.length());
outer: for (char c : word.toCharArray()) {
for (char h : undesirable) {
if (c == h) continue outer;
}
sb.append(c);
}
sb.toString();
}
public static void testAsString() {
String word = "Hello, t-his is; an- (example) line.";
String undesirable = ",.;-()";
int len1 = undesirable.length();
int len2 = word.length();
StringBuilder sb = new StringBuilder(len2);
outer: for (int j = 0; j < len2; j++) {
char c = word.charAt(j);
for (int i = 0; i < len1; i++) {
if (c == undesirable.charAt(i)) continue outer;
}
sb.append(c);
}
sb.toString();
}
private static final Pattern regex = Pattern.compile("[,\\.;\\-\\(\\)]");
public static void testRegex() {
String word = "Hello, t-his is; an- (example) line.";
String result = regex.matcher(word).replaceAll("");
}
}
The output on my machine:
Without regex, but using copied arrays: 5880
With precompiled regex: 11011
Without regex, but using string: 3844
Here is a solution to do this with minimal effort; the toRemove string contains all character you don't want to see in the output:
public static String removeChars(final String input, final String toRemove)
{
final StringBuilder sb = new StringBuilder(input.length());
final CharBuffer buf = CharBuffer.wrap(input);
char c;
while (buf.hasRemaining()) {
c = buf.get();
if (toRemove.indexOf(c) == -1)
sb.append(c);
}
return sb.toString();
}
If you use Java 8 you can even use this (unfortunately there's no CharStream so the casts are necessary...):
public static String removeChars(final String input, final String toRemove)
{
final StringBuilder sb = new StringBuilder(input.length());
input.chars().filter(c -> toRemove.indexOf((char) c) == -1)
.forEach(i -> sb.append((char) i));
return sb.toString();
}
You could try using a regular expression with Java's String.replaceAll method:
word = word.replaceAll(",|\.|;|-|\(|\)", "");
If you're not familiar with regular expressions, | means "or". So we are essentially saying , or . or ; or - or ( or ).
See more: Java documentation for String.replaceAll
Edit:
As mentioned, my previous version will not compile. Just for the sake of correctness (even though it has been pointed out that this is not the optimal solution), here is the corrected version of my regex:
word = word.replaceAll(",|\\.|;|-|\\(|\\)", "");

Compression algorithm in java

My goal is to write a program that compresses a string, for example:
input: hellooopppppp!
output:he2l3o6p!
Here is the code I have so far, but there are errors.
When I have the input: hellooo
my code outputs: hel2l3o
instead of: he213o
the 2 is being printed in the wrong spot, but I cannot figure out how to fix this.
Also, with an input of: hello
my code outputs: hel2l
instead of: he2lo
It skips the last letter in this case all together, and the 2 is also in the wrong place, an error from my first example.
Any help is much appreciated. Thanks so much!
public class compressionTime
{
public static void main(String [] args)
{
System.out.println ("Enter a string");
//read in user input
String userString = IO.readString();
//store length of string
int length = userString.length();
System.out.println(length);
int count;
String result = "";
for (int i=1; i<=length; i++)
{
char a = userString.charAt(i-1);
count = 1;
if (i-2 >= 0)
{
while (i<=length && userString.charAt(i-1) == userString.charAt(i-2))
{
count++;
i++;
}
System.out.print(count);
}
if (count==1)
result = result.concat(Character.toString(a));
else
result = result.concat(Integer.toString(count).concat(Character.toString(a)));
}
IO.outputStringAnswer(result);
}
}
I would
count from 0 as that is how indexes work in Java. Your code will be simpler.
would compare the current char to the next one. This will avoid printing the first character.
wouldn't compress ll as 2l as it is no smaller. Only sequences of at least 3 will help.
try to detect if a number 3 to 9 has been used and at least print an error.
use the debugger to step through the code to understand what it is doing and why it doesn't do what you think it should.
I am doing it this way. Very simple:
public static void compressString (String string) {
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < string.length(); i++) {
int count = 1;
while (i + 1 < string.length()
&& string.charAt(i) == string.charAt(i + 1)) {
count++;
i++;
}
if (count > 1) {
stringBuffer.append(count);
}
stringBuffer.append(string.charAt(i));
}
System.out.println("Compressed string: " + stringBuffer);
}
You can accomplish this using a nested for loops and do something simial to:
count = 0;
String results = "";
for(int i=0;i<userString.length();){
char begin = userString.charAt(i);
//System.out.println("begin is: "+begin);
for(int j=i+1; j<userString.length();j++){
char next = userString.charAt(j);
//System.out.println("next is: "+next);
if(begin == next){
count++;
}
else{
System.out.println("Breaking");
break;
}
}
i+= count+1;
if(count>0){
String add = begin + "";
int tempcount = count +1;
results+= tempcount + add;
}
else{
results+= begin;
}
count=0;
}
System.out.println(results);
I tested this output with Hello and the result was He2lo
also tested with hellooopppppp result he2l3o6p
If you don't understand how this works, you should learn regular expressions.
public String rleEncodeString(String in) {
StringBuilder out = new StringBuilder();
Pattern p = Pattern.compile("((\\w)\\2*)");
Matcher m = p.matcher(in);
while(m.find()) {
if(m.group(1).length() > 1) {
out.append(m.group(1).length());
}
out.append(m.group(2));
}
return out.toString();
}
Try something like this:
public static void main(String[] args) {
System.out.println("Enter a string:");
Scanner IO = new Scanner(System.in);
// read in user input
String userString = IO.nextLine() + "-";
int length = userString.length();
int count = 0;
String result = "";
char new_char;
for (int i = 0; i < length; i++) {
new_char = userString.charAt(i);
count++;
if (new_char != userString.charAt(i + 1)) {
if (count != 1) {
result = result.concat(Integer.toString(count + 1));
}
result = result.concat(Character.toString(new_char));
count = 0;
}
if (userString.charAt(i + 1) == '-')
break;
}
System.out.println(result);
}
The problem is that your code checks if the previous letter, not the next, is the same as the current.
Your for loops basically goes through each letter in the string, and if it is the same as the previous letter, it figures out how many of that letter there is and puts that number into the result string. However, for a word like "hello", it will check 'e' and 'l' (and notice that they are preceded by 'h' and 'e', receptively) and think that there is no repeat. It will then get to the next 'l', and then see that it is the same as the previous letter. It will put '2' in the result, but too late, resulting in "hel2l" instead of "he2lo".
To clean up and fix your code, I recommend the following to replace your for loop:
int count = 1;
String result = "";
for(int i=0;i<length;i++) {
if(i < userString.length()-1 && userString.charAt(i) == userString.charAt(i+1))
count++;
else {
if(count == 1)
result += userString.charAt(i);
else {
result = result + count + userString.charAt(i);
count = 1;
}
}
}
Comment if you need me to explain some of the changes. Some are necessary, others optional.
Here is the solution for the problem with better time complexity:
public static void compressString (String string) {
LinkedHashSet<String> charMap = new LinkedHashSet<String>();
HashMap<String, Integer> countMap = new HashMap<String, Integer>();
int count;
String key;
for (int i = 0; i < string.length(); i++) {
key = new String(string.charAt(i) + "");
charMap.add(key);
if(countMap.containsKey(key)) {
count = countMap.get(key);
countMap.put(key, count + 1);
}
else {
countMap.put(key, 1);
}
}
Iterator<String> iterator = charMap.iterator();
String resultStr = "";
while (iterator.hasNext()) {
key = iterator.next();
count = countMap.get(key);
if(count > 1) {
resultStr = resultStr + count + key;
}
else{
resultStr = resultStr + key;
}
}
System.out.println(resultStr);
}

how can i calculate the number of specific chars in a string?

Given a string how can i figure out the number of times each char in a string repeats itself
ex: aaaabbaaDD
output: 4a2b2a2D
public static void Calc() {
Input();
int count = 1;
String compressed = "";
for (int i = 0; i < input.length(); i++) {
if (lastChar == input.charAt(i)) {
count++;
compressed += Integer.toString(count) + input.charAt(i);
}
else {
lastChar = input.charAt(i);
count = 1;
}
}
System.out.println(compressed);
}
What you'r looking for is "Run-length encoding". Here is the working code to do that;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RunLengthEncoding {
public static String encode(String source) {
StringBuffer dest = new StringBuffer();
// iterate through input string
// Iterate the string N no.of.times where N is size of the string to find run length for each character
for (int i = 0; i < source.length(); i++) {
// By default run Length for all character is one
int runLength = 1;
// Loop condition will break when it finds next character is different from previous character.
while (i+1 < source.length() && source.charAt(i) == source.charAt(i+1)) {
runLength++;
i++;
}
dest.append(runLength);
dest.append(source.charAt(i));
}
return dest.toString();
}
public static String decode(String source) {
StringBuffer dest = new StringBuffer();
Pattern pattern = Pattern.compile("[0-9]+|[a-zA-Z]");
Matcher matcher = pattern.matcher(source);
while (matcher.find()) {
int number = Integer.parseInt(matcher.group());
matcher.find();
while (number-- != 0) {
dest.append(matcher.group());
}
}
return dest.toString();
}
public static void main(String[] args) {
String example = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW";
System.out.println(encode(example));
System.out.println(decode("1W1B1W1B1W1B1W1B1W1B1W1B1W1B"));
}
}
This program first finds the unique characters or numbers in a string. It will then check the frequency of occurance.
This program considers capital and small case as different characters. You can modify it if required by using ignorecase method.
import java.io.*;
public class RunLength {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException {
System.out.println("Please enter the string");
String str = br.readLine();//the input string is in str
calculateFrequency(str);
}
private static void calculateFrequency(String str) {
int length = str.length();
String characters[] = new String[length];//to store all unique characters in string
int frequency[] = new int[length];//to store the frequency of the characters
for (int i = 0; i < length; i++) {
characters[i] = null;
frequency[i] = 0;
}
//To get unique characters
char temp;
String temporary;
int uniqueCount = 0;
for (int i = 0; i < length; i++) {
int flag = 0;
temp = str.charAt(i);
temporary = "" + temp;
for (int j = 0; j < length; j++) {
if (characters[j] != null && characters[j].equals(temporary)) {
flag = 1;
break;
}
}
if (flag == 0) {
characters[uniqueCount] = temporary;
uniqueCount++;
}
}
// To get the frequency of the characters
for(int i=0;i<length;i++){
temp=str.charAt(i);
temporary = ""+temp;
for(int j=0;i<characters.length;j++){
if(characters[j].equals(temporary)){
frequency[j]++;
break;
}
}
}
// To display the output
for (int i = 0; i < length; i++) {
if (characters[i] != null) {
System.out.println(characters[i]+" "+frequency[i]);
}
}
}}
Some hints: In your code sample you also need to reset count to 0 when the run ends (when you update lastChar). And you need to output the final run (after the loop is done). And you need some kind of else or continue between the two cases.
#Balarmurugan k's solution is better - but just by improving upon your code I came up with this -
String input = "aaaabbaaDD";
int count = 0;
char lastChar = 0;
int inputSize = input.length();
String output = "";
for (int i = 0; i < inputSize; i++) {
if (i == 0) {
lastChar = input.charAt(i);
count++;
} else {
if (lastChar == input.charAt(i)) {
count++;
} else {
output = output + count + "" + lastChar;
count = 1;
lastChar = input.charAt(i);
}
}
}
output = output + count + "" + lastChar;
System.out.println(output);

Categories