I want split a string for example: 5121321 in 5 121 321, every 3 is a ' '.
I have that code:
private void compor()
{
String dinheiro="5121321";
char aux[]= new char[dinheiro.length()];
for(int i=0;i<dinheiro.length();i++)
{
aux[i]=dinheiro.charAt(i);
}
int flag=0;
String total="";
for(int i=0;i<dinheiro.length();i++)
{
if(flag==3)
{
total+=' ';
flag=0;
}
total += String.valueOf(aux[i]);
flag++;
}
TextView txt = (TextView) findViewById(R.id.textView3);
txt.setText(String.valueOf(total));
}
The problem is the output of this is: 512 132 1 and i want 5 121 321. Sorry my english.
Somebody can help me?Thanks.
It looks like you're just trying to do general numeric formatting. A simple solution using framework utilities is:
public static String splitNumericString(String numeric) throws NumberFormatException {
// Create a new DecimalFormatSymbols instance and set the
// grouping separator to a space character
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setGroupingSeparator(' ');
// Construct a new NumberFormat defining a 3 digit grouping
// pattern
NumberFormat format = new DecimalFormat("#,###", symbols);
// Converts the string into an actual numeric value
long number = Long.parseLong(numeric);
// Return the formatted string
return format.format(number);
}
EDIT: Given #Squonk's info, this becomes a one-liner:
return NumberFormat.getInstance(Locale.FRANCE).format(Long.parseLong(numeric));
Although you should catch the NumberParseException in case of an improperly formatted input string.
(1) Just loop backwards through the string. And use pretty much the same idea you used. This will split it the way you want. (2) Alternatively, you can calculate where the first full triple starts by using the % (modulo) operator (I mean string length % 3).
Sample code for approach (2):
public class Test007 {
public static void main(String[] args) {
String dinheiro="5121322";
int i = dinheiro.length() % 3;
String s1 = "";
s1 = dinheiro.substring(0, i);
String s2 = "";
for (int k=i; k<dinheiro.length(); k+=3){
if (k!=i || i>0){
s2 += " ";
}
s2 += dinheiro.substring(k, k+3);
}
System.out.println(s1 + s2);
}
}
Instead of catenating in a loop, use a stringbuilder:
String input = /*...*/;
StringBuilder sb = new StringBuilder();
int i = 2;
for (char c : input.toCharArray()) {
sb.append(c);
i++;
if (i == 3) {
sb.append(' ');
i = 0;
}
}
String result = sb.toString();
Here's a variant to Peter Petrov's solution:
public static String group(String in) {
// Get the length of the first group
int i = (in.length() - 1) % 3 + 1;
// Add the first group
String out = in.substring(0, i);
// Add the other groups, each prefixed with a space
for (int k = i; k < in.length(); k += 3){
out += " " + in.substring(k, k + 3);
}
return out;
}
We get the length of the first group, we initialize the output with that first group and then we go over the remainder of the input to append one group of 3 digits at a time. That's really all there is to it.
The tricky bit is in the first line. Just using in.length() % 3 doesn't work correctly, since that prevents the first group from ever having 3 digits. For example, an input of "123456" would lead to i == 0 and an output of " 123 456" (note the unwanted space at the start). Peter uses an if check to deal with this case, but it turns out you can also handle it by changing i a bit.
We want the relation between in.length() and i to be like this:
in.length() | i | (in.length() - 1) % 3
------------------------------------------
0 | 0 | -1
1 | 1 | 0
2 | 2 | 1
3 | 3 | 2
4 | 1 | 0
5 | 2 | 1
... | ... | ...
Subtracting one before the modulo and adding it back afterwards gives us this relation (the partial result after the modulo is in the third column). It even handles the special case where in is the empty string! :-P
The solution is easier to write with simple arithmetic than with string manipulation:
public static String groupDigits(int amount) {
String total = "";
while (amount > 0) {
Integer digits = amount % 1000;
amount = amount / 1000;
total = digits.toString() + " " + total;
}
return total;
}
Related
Encoding format: introduce * to indicate "repeat from beginning". Example. Input-{a,b,a,b,c,a,b,a,b,c,d} can be written as {a , b, * ,c, * , d}. Output:5; E.g 2: ABCABCE, output- 5.
Here * means repeat from beginning. For example if given String is ABCABCABCABC , it will return ABC**, another example is if String is ABCABCABC, it will return ABC*ABC.
I have the below code but this code assumes that the string will contain the repetitive pattern only and no other characters, I want to modify it to check :
1. Which pattern is repeating
2. Ignore non repeating patterns
2. encode that pattern according to the problem statement
import java.util.Scanner;
public class Magicpotion {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the string:");
String str = sc.nextLine();
int len = str.length();
if (len != 0) {
int lenby3 = len / 3;
int starcount = ( int).(Math.log(lenby3) / Math.log(2));
int leftstring = (lenby3 - (int) Math.pow(2, starcount));
int resultlen = (1 * 3) + starcount + (leftstring * 3);
System.out.println("ResultLength: " + resultlen);
System.out.print("ABC");
for (int i = 0; i < starcount; i++) {
System.out.print("*");
}
for (int i = 0; i < leftstring; i++) {
System.out.print("ABC");
}
} else
System.out.println("ResultLength: " + 0);
}
}
Here my assumption is that ABC will always be repeating pattern , hence I have divided the length by 3. I want to generalise it such that I find the repeating pattern which can be a AB or BC or ABCD and proceed accordingly.
This looks like homework. So instead of a full solution just some hints:
You can process the input string character by character and encode as you go. If you have at some point already read k characters and the next k characters are exactly the same, output a * and advance to position 2k.
Otherwise, output the next input character and advance position to k+1.
As mentioned by dyukha this algorithm does not always result in the shortest possible encoding. If this is required some more effort has to be put into the search.
This problem can be solved using dynamic programming.
Assume that you processed your stay at some position i. You want to understand what it the minimal length of encoding of str[0..i]. Let's call it ans[i]. You have two options:
Just add i-th character to the encoding. So the length is ans[i-1] + 1.
You may write *, when possible. In this case the length is ans[i / 2] + 1 or something like this.
The final length is in ans[n-1]. You can store how you obtained ans[i] to recover the encoding itself.
Checking whether you can write * can be optimized, using some hashing (to obtain O(n) solution instead of O(n^2)).
The difference with Henry's solution is that he always applies * when it's possible. It's not clear to me that it results into the minimal length (if I understood correctly, aaaaaa is a counterexample), so I'm giving a solution I'm sure about.
/**
* #author mohamed ali
* https://www.linkedin.com/in/oo0shaheen0oo/
*/
public class Magic_potion_encoding
{
private static int minimalSteps( String ingredients )
{
StringBuilder sb = new StringBuilder(ingredients);
for(int i =0;i<sb.length();i++)
{
char startChar = sb.charAt(i);
int walkingIndex1=i;
int startIndex2 =sb.toString().indexOf(startChar,i+1);
int walkingIndex2=startIndex2;
while(walkingIndex2 !=-1 && walkingIndex2<sb.length() && sb.charAt(walkingIndex1) == sb.charAt(walkingIndex2) )
{
if(walkingIndex1+1==startIndex2)
{
String subStringToBeEncoded = sb.substring(i,walkingIndex2+1);//substring the string found and the original "substring does not include the last index hence the +1
int matchStartIndex = sb.indexOf(subStringToBeEncoded,walkingIndex2+1);// look for first match for the whole string matched
int matchEndeIndex= matchStartIndex+subStringToBeEncoded.length();
int origStartIndex=i;
int origEndIndex = i+subStringToBeEncoded.length();
if (matchStartIndex!=-1 )
{
if(origEndIndex==matchStartIndex)
{
sb.replace(matchStartIndex,matchEndeIndex,"*");
}
else
{
while(matchStartIndex!=-1 && matchEndeIndex<sb.length() && sb.charAt(origEndIndex) == sb.charAt(matchEndeIndex) )
{
if(origEndIndex==matchStartIndex-1)// if the index of the 2 strings are right behind one another
{
sb.replace(matchStartIndex,matchEndeIndex+1,"*");
}
else
{
origEndIndex++;
matchEndeIndex++;
}
}
}
}
sb.replace(startIndex2,walkingIndex2+1,"*");
break;
}
walkingIndex1++;
walkingIndex2++;
}
}
System.out.println("orig= " + ingredients + " encoded = " + sb);
return sb.length();
}
public static void main( String[] args )
{
if ( minimalSteps("ABCABCE") == 5 &&
minimalSteps("ABCABCEA") == 6 &&
minimalSteps("abbbbabbbb") == 5 &&
minimalSteps("abcde") == 5 &&
minimalSteps("abcbcbcbcd") == 6 &&
minimalSteps("ababcababce") == 6 &&
minimalSteps("ababababxx") == 6 &&
minimalSteps("aabbccbbccaabbccbbcc") == 8)
{
System.out.println( "Pass" );
}
else
{
System.out.println( "Fail" );
}
}
}
Given that the repetitions are from the beginning, every such repeating substring will have the very first character of the given string. [Every repetition needs to be represented by a "star". (i.e ABCABCABC ans = ABC** ) . If all sequential repetitions are to be represented with one "star". (i.e ABCABCABC and = ABC* ), a slight modification to (2) will do the thing (i.e remove the if case where the just a star is added)]
Divide the given string to substrings based on the first character.
Eg. Given String = "ABABCABD"
Sub Strings = {"AB", "ABC", "AB", "ABD"}
Just traverse through the list of substrings and get the required result. I've used a map here, to make the search easy.
Just a rough write up.
SS = {"AB", "ABC", "AB", "ABD"};
result = SS[0];
Map<string, bool> map;
map.put(SS[0],true);
for (i = 1; i < SS.length; i++){
if (map.hasKey(SS[i])){
result += "*";
}
else {
res = nonRepeatingPart(SS[i], map);
result += "*" + res;
map.put(SS[i], true);
}
}
String nonRepeatingPart(str, map){
for (j = str.length-1; j >= 0; j--){
if (map.hasKey(str.subString(0, j))){
return str.subString(j, str.length-1);
}
}
return throwException("Wrong Input");
}
string getCompressed(string str){
string res;
res += str[0];
int i=1;
while(i<str.size()){
//check if current char is the first char in res
char curr = str[i];
if(res[0]==curr){
if(str.substr(0,i)==str.substr(i,i)){
res += '*';
i+=i; continue;
}else{
res += curr;
i++; continue;
}
}else {
res += curr;
i++; continue;
}
}
return res;
}
int main()
{
string s = "ABCABCABC";
string res = getCompressed(s);
cout<<res.size();
return 0;
}
for example I have String: 61109010140000071219812874 and I want to apply algorithm, which will transofmation String in the following way:
611 09-010-14-000-00-712-19-812-87-4
as you can see, the point is to select the first three letters of the String, then add a white space, then add two dashes after two characters, then three, then again two characters. Something like:
### ##-###-##-###-##-###-##-###
Only I would like my algorithm to be universal. For example, for a string 6110901 output is: 611 09-01, for a string 61109010, output is: 611 09-010
I tried to use StringBuilder and the addCharAt method, but unfortunately it overwrites my string.
The above answers in the comments work but if you want a regular loop that builds what you want, this should do the trick:
public static void main(String args[]) {
String str = "61109010140000071219812874";
String output = "";
int segment = 2;
for(int i = 0; i < str.length(); i += segment){
segment = segment == 3 ? 2 : 3;
String seg = str.substring(i, Math.min(i + segment, str.length()));
char next = i == 0 ? ' ' : '-';
seg += next;
output += seg;
}
output = output.substring(0, output.length() - 1);
System.out.println(output); //611 09-010-14-000-00-712-19-812-87-4
}
Hi guys I am busy with breaking / splitting Strings.
However the String is not fixed so when the input changes the program still has to work with any character input.
Till now I got this far but I got lost.
I have made an array of characters and set the size of the array equal to the lenght of any string that is will get as input. I made a for loop to loop through the characters of a string.
how do I insert my string now into the array because I know that my string is not yet in there? Then when its finally looping through the characters of my string is has to printout numbers and operands on different lines. So the ouput would look like in this case like this;
1
+
3
,
432
.
123
etc
I want to do this without using matchers,scanner, etc. I want to use basic Java techniques like you learn in the first 3 chapters of HeadfirstJava.
public class CharAtExample {
public static void main(String[] args) {
// This is the string we are going to break down
String inputString = "1+3,432.123*4535-24.4";
int stringLength = inputString.length();
char[] destArray = new char[stringLength];{
for (int i=0; i<stringLength; i++);
}
You could use Character.isDigit(char) to distinguish numeric and not numeric chars as actually this is the single criteria to group multiple chars in a same line.
It would give :
public static void main(String[] args) {
String inputString = "1+3,432.123*4535-24.4";
String currentSequence = "";
for (int i = 0; i < inputString.length(); i++) {
char currentChar = inputString.charAt(i);
if (Character.isDigit(currentChar)) {
currentSequence += currentChar;
continue;
}
System.out.println(currentSequence);
System.out.println(currentChar);
currentSequence = "";
}
// print the current sequence that is a number if not printed yet
if (!currentSequence.equals("")) {
System.out.println(currentSequence);
}
}
Character.isDigit() relies on unicode category.
You could code it yourself such as :
if (Character.getType(currentChar) == Character.DECIMAL_DIGIT_NUMBER) {...}
Or you could code it still at a lower level by checking that the int value of the char is included in the range of ASCII decimal values for numbers:
if(currentChar >= 48 && currentChar <= 57 ) {
It outputs what you want :
1
+
3
,
432
.
123
*
4535
-
24
.
4
It's easier than you might think.
First: to get an array with the chars of your string you just use the toCharArray() method that all strings have. ex. myString.toCharArray()
Second: When you see that a character is not a number, you want to move to the next line, print the character and then move to the next line again. The following code does exactly that :
public class JavaApplication255 {
public static void main(String[] args) {
String inputString = "1+3,432.123*4535-24.4";
char[] destArray = inputString.toCharArray();
for (int i = 0 ; i < destArray.length ; i++){
char c = destArray[i];
if (isBreakCharacter(c)){
System.out.println("\n" + c);
} else {
System.out.print(c);
}
}
}
public static boolean isBreakCharacter(char c){
return c == '+' || c == '*' || c == '-' || c == '.' || c == ',' ;
}
char[] charArray = inputString.toCharArray();
Here is a possible solution where we go character by character and either add to an existing string which will be our numbers or it adds the string to the array, clears the current number and then adds the special characters. Finally we loop through the array as many times as we find a number or non-number character. I used the ASCII table to identify a character as a digit, the table will come in handy throughout your programming career. Lastly I changed the array to a String array because a character can't hold a number like "432", only '4' or '3' or '2'.
String inputString = "1+3,432.123*4535-24.4";
int stringLength = inputString.length();
String[] destArray = new String[stringLength];
int destArrayCount = 0;
String currentString = "";
for (int i=0; i<stringLength; i++)
{
//check it's ascii value if its between 0 (48) and 9 (57)
if(inputString.charAt(i) >= 48 && inputString.charAt(i) <= 57 )
{
currentString += inputString.charAt(i);
}
else
{
destArray[destArrayCount++] = currentString;
currentString = "";
//we know we don't have a number at i so its a non-number character, add it
destArray[destArrayCount++] = "" + inputString.charAt(i);
}
}
//add the last remaining number
destArray[destArrayCount++] = currentString;
for(int i = 0; i < destArrayCount; i++)
{
System.out.println("(" + i + "): " + destArray[i]);
}
IMPORTANT - This algorithm will fail if a certain type of String is used. Can you find a String where this algorithm fails? What can you do to to ensure the count is always correct and not sometimes 1 greater than the actual count?
I am trying for find the Java code which:
1) Checks whether the String contains any consecutive integers
2) If it contains consecutive integers, then concatenate them i.e. my current message has integers separated by space only, so I need a way to concatenate those space separate integers. Eg:
message1 = "My no is 9543 21 00 10"
desired output = "My no is 9543210010"
message2 = "You can reach 2 me at 42315 468"
desired output = "You can reach 2 me at 42315468"
My main problem is to solve the above issue for phone numbers ie to concatenate space separated phone numbers together, so if someone has a different approach to solve this, please let me know.
I tried the following code but it doesn't work when string ends with a space:
if(message.matches(".*\\d.*")){
for (int i = 0; i <= message.length() -2 ; ++i){
if ((Character.isDigit(message.charAt(i))) && message.charAt(i+1) == ' ' && (Character.isDigit(message.charAt(i+2)))) {
StringBuilder sb = new StringBuilder(message);
sb.deleteCharAt(i+1);
message = sb.toString();
}
}
}
A community wiki answer based on peshmo's comment.
In other words, you are trying to remove spaces which are surrounded by digits.
message = message.replaceAll("(?<=\\d)\\s+(?=\\d)","");
This regex expression will do that. Try it here: https://regex101.com/r/qR33XN/1
This is untested code, just written in notepad but I think you will get the gist.
Basicly, split the string into an array with delimiter of a space(' '), glue everything back together. Add a space if index + 1 isn't a number otherwise don't add a space.
I hope this helps
String msg = "abc 1 2 3 333 yoo"
String[] splitted = msg.Split(' ');
String output = "";
for(int i = 0; i < splitted.Length - 1; i++) {
output += splitted[i];
if(i + 1 < splitted.Length - 1) {
if(isInteger(splitted[i]) && isInteger(splitted[i+1]))
continue;
}
output += " "
}
output = output.Trim();
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
} catch(NullPointerException e) {
return false;
}
// only got here if we didn't return false
return true;
}
Let's say I have a couple variable and I want to format them so they're all aligned, but the variables are different lengths. For example:
String a = "abcdef";
String b = "abcdefhijk";
And I also have a price.
double price = 4.56;
How would I be able to format it so no matter how long the String is, they are aligned either way?
System.out.format("%5s %10.2f", a, price);
System.out.format("%5s %10.2f", b, price);
For example, the code above would output something like this:
abcdef 4.56
abcdefhijk 4.56
But I want it to output something like this:
abcdef 4.56
abcdefhijk 4.56
How would I go about doing so? Thanks in advance.
Use fixed size format:
Using format strings with fixed size permits to print the strings in a
table-like appearance with fixed size columns:
String rowsStrings[] = new String[] {"1",
"1234",
"1234567",
"123456789"};
String column1Format = "%-3.3s"; // fixed size 3 characters, left aligned
String column2Format = "%-8.8s"; // fixed size 8 characters, left aligned
String column3Format = "%6.6s"; // fixed size 6 characters, right aligned
String formatInfo = column1Format + " " + column2Format + " " + column3Format;
for(int i = 0; i < rowsStrings.length; i++) {
System.out.format(formatInfo, rowsStrings[i], rowsStrings[i], rowsStrings[i]);
System.out.println();
}
Output:
1 1 1
123 1234 1234
123 1234567 123456
123 12345678 123456
In your case you could find the maximum length of the strings you want to display and use that to create the appropriate format information, for example:
// find the max length
int maxLength = Math.max(a.length(), b.length());
// add some space to separate the columns
int column1Length = maxLength + 2;
// compose the fixed size format for the first column
String column1Format = "%-" + column1Length + "." + column1Length + "s";
// second column format
String column2Format = "%10.2f";
// compose the complete format information
String formatInfo = column1Format + " " + column2Format;
System.out.format(formatInfo, a, price);
System.out.println();
System.out.format(formatInfo, b, price);
Put negative sign in front of your format specifier so instead of printing 5 spaces to the left of your float value, it adjusts the space on the right until you find the ideal position. It should be fine
You can achieve it as below-
String a = "abcdef";
String b = "abcdefhijk";
double price = 4.56;
System.out.println(String.format("%-10s %-10.2f", a, price));
System.out.println(String.format("%-10s %-10.2f", b, price));
output:
abcdef 4.56
abcdefhijk 4.56
You can find the longest String, and then use Apache commons-lang StringUtils to leftPad both of your String(s). Something like,
int len = Math.max(a.length(), b.length()) + 2;
a = StringUtils.leftPad(a, len);
b = StringUtils.leftPad(b, len);
Or, if you can't use StringUtils - you could implement leftPad. First a method to generate String of whitespace. Something like,
private static String genString(int len) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
sb.append(' ');
}
return sb.toString();
}
Then use it to implement leftPad - like,
private static String leftPad(String in, int len) {
return new StringBuilder(in) //
.append(genString(len - in.length() - 1)).toString();
}
And, I tested it like,
int len = Math.max(a.length(), b.length()) + 2;
System.out.format("%s %.2f%n", leftPad(a, len), price);
System.out.format("%s %.2f%n", leftPad(b, len), price);
Which outputs (as I think you wanted)
abcdef 4.56
abcdefhijk 4.56
private String addEnoughSpacesInBetween(String firstStr, String secondStr){
if (!firstStr.isEmpty() && !secondStr.isEmpty()){
String space = " ";
int totalAllowed = 55;
int multiplyFor = totalAllowed - (firstStr.length() + secondStr.length());
return StringUtils.repeat(space,multiplyFor);
}
return null;
}