String Manipulation insert a character every 4th character [duplicate] - java

This question already has answers here:
Putting char into a java string for each N characters
(12 answers)
Closed 6 years ago.
In Android if I have an edit text and the user entered 123456789012, how could I get the program to insert a dash every 4th character. ie: 1234-5678-9012?
I guess you need to say something along the lines of:-
a=Characters 1~4, b=Characters 5~8, c=Characters 9-12, Result = a + "-" + b + "-" + c. But I am unsure of how that would look in Android.
Many thanks for any help.

String s = "123456789012";
String s1 = s.substring(0, 4);
String s2 = s.substring(4, 8);
String s3 = s.substring(8, 12);
String dashedString = s1 + "-" + s2 + "-" + s3;
//String.format is extremely slow. Just concatenate them, as above.
substring() Reference

Or another alternative way using a StringBuilder rather than to split the string in multiple parts and then join them :
String original = "123456789012";
int interval = 4;
char separator = '-';
StringBuilder sb = new StringBuilder(original);
for(int i = 0; i < original.length() / interval; i++) {
sb.insert(((i + 1) * interval) + i, separator);
}
String withDashes = sb.toString();

Alternative way:
String original = "123456789012";
int dashInterval = 4;
String withDashes = original.substring(0, dashInterval);
for (int i = dashInterval; i < original.length(); i += dashInterval) {
withDashes += "-" + original.substring(i, i + dashInterval);
}
return withDashes;
If you needed to pass strings with lengths that were not multiples of the dashInterval you'd have to write an extra bit to handle that to prevent index out of bounds nonsense.

Related

How to insert char at specific location throughout the string? [duplicate]

I'm getting in an int with a 6 digit value. I want to display it as a String with a decimal point (.) at 2 digits from the end of int. I wanted to use a float but was suggested to use String for a better display output (instead of 1234.5 will be 1234.50). Therefore, I need a function that will take an int as parameter and return the properly formatted String with a decimal point 2 digits from the end.
Say:
int j= 123456
Integer.toString(j);
//processing...
//output : 1234.56
As mentioned in comments, a StringBuilder is probably a faster implementation than using a StringBuffer. As mentioned in the Java docs:
This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.
Usage :
String str = Integer.toString(j);
str = new StringBuilder(str).insert(str.length()-2, ".").toString();
Or if you need synchronization use the StringBuffer with similar usage :
String str = Integer.toString(j);
str = new StringBuffer(str).insert(str.length()-2, ".").toString();
int j = 123456;
String x = Integer.toString(j);
x = x.substring(0, 4) + "." + x.substring(4, x.length());
int yourInteger = 123450;
String s = String.format("%6.2f", yourInteger / 100.0);
System.out.println(s);
Using ApacheCommons3 StringUtils, you could also do
int j = 123456;
String s = Integer.toString(j);
int pos = s.length()-2;
s = StringUtils.overlay(s,".", pos, pos);
it's basically substring concatenation but shorter if you don't mind using libraries, or already depending on StringUtils
In most use-cases, using a StringBuilder (as already answered) is a good way to do this. However, if performance matters, this may be a good alternative.
/**
* Insert the 'insert' String at the index 'position' into the 'target' String.
*
* ````
* insertAt("AC", 0, "") -> "AC"
* insertAt("AC", 1, "xxx") -> "AxxxC"
* insertAt("AB", 2, "C") -> "ABC
* ````
*/
public static String insertAt(final String target, final int position, final String insert) {
final int targetLen = target.length();
if (position < 0 || position > targetLen) {
throw new IllegalArgumentException("position=" + position);
}
if (insert.isEmpty()) {
return target;
}
if (position == 0) {
return insert.concat(target);
} else if (position == targetLen) {
return target.concat(insert);
}
final int insertLen = insert.length();
final char[] buffer = new char[targetLen + insertLen];
target.getChars(0, position, buffer, 0);
insert.getChars(0, insertLen, buffer, position);
target.getChars(position, targetLen, buffer, position + insertLen);
return new String(buffer);
}
For Kotlin dudes ;) from the accepted answer (#MikeThomsen's)
fun String.insert(insertAt: Int, string: String): String {
return this.substring(0, insertAt) + string + this.substring(insertAt, this.length)
}
Test ✅
"ThisTest".insert(insertAt = 4, string = "Is").should.equal("ThisIsTest")
String.format("%0d.%02d", d / 100, d % 100);
You could use
System.out.printf("%4.2f%n", ((float)12345)/100));
As per the comments, 12345/100.0 would be better, as would the use of double instead of float.
If you are using a system where float is expensive (e.g. no FPU) or not allowed (e.g. in accounting) you could use something like this:
for (int i = 1; i < 100000; i *= 2) {
String s = "00" + i;
System.out.println(s.substring(Math.min(2, s.length() - 2), s.length() - 2) + "." + s.substring(s.length() - 2));
}
Otherwise the DecimalFormat is the better solution. (the StringBuilder variant above won't work with small numbers (<100)
I think a simpler and more elegant solution to insert a String in a certain position would be this one-liner:
target.replaceAll("^(.{" + position + "})", "$1" + insert);
For example, to insert a missing : into a time String:
"-0300".replaceAll("^(.{3})", "$1:");
What it does is, matches position characters from the beginning of the string, groups that, and replaces the group with itself ($1) followed by the insert string. Mind the replaceAll, even though there's always one occurrence, because the first parameter must be a regex.
Of course it does not have the same performance as the StringBuilder solution, but I believe the succinctness and elegance as a simple and easier to read one-liner (compared to a huge method) is sufficient for making it the preferred solution in most non performance-critical use-cases.
Note I'm solving the generic problem in the title for documentation reasons, of course if you are dealing with decimal numbers you should use the domain-specific solutions already proposed.
There are good answers here, but with Kotlin extensions addition we can do it even more simply:
val indexWhereInsertIsIntended = 2
val inputString = "2408"
val resultingString = inputString.toCharArray().toMutableList()
.also {
it.add(indexWhereInsertIsIntended, '/')
}.joinToString("")
Result = 24/08
This example shows a card expiry date, and slash (/) is intended at 2nd Index. So the resulting index in this case will have / at 2nd index.
If you want to replace and not add:
val indexWhereInsertIsIntended = 2
val inputString = "2408"
val resultingString = inputString.toCharArray()
.also {
it[indexWhereInsertIsIntended] = '/'
}.joinToString("")
Result = 24/0
public static void main(String[] args) {
char ch='m';
String str="Hello",k=String.valueOf(ch),b,c;
System.out.println(str);
int index=3;
b=str.substring(0,index-1 );
c=str.substring(index-1,str.length());
str=b+k+c;
}
// Create given String and make with size 30
String str = "Hello How Are You";
// Creating StringBuffer Object for right padding
StringBuffer stringBufferRightPad = new StringBuffer(str);
while (stringBufferRightPad.length() < 30) {
stringBufferRightPad.insert(stringBufferRightPad.length(), "*");
}
System.out.println("after Left padding : " + stringBufferRightPad);
System.out.println("after Left padding : " + stringBufferRightPad.toString());
// Creating StringBuffer Object for right padding
StringBuffer stringBufferLeftPad = new StringBuffer(str);
while (stringBufferLeftPad.length() < 30) {
stringBufferLeftPad.insert(0, "*");
}
System.out.println("after Left padding : " + stringBufferLeftPad);
System.out.println("after Left padding : " + stringBufferLeftPad.toString());
Try this :
public String ConvertMessage(String content_sendout){
//use unicode (004E00650077) need to change to hex (&#x004E&#x;0065&#x;0077;) first ;
String resultcontent_sendout = "";
int i = 4;
int lengthwelcomemsg = content_sendout.length()/i;
for(int nadd=0;nadd<lengthwelcomemsg;nadd++){
if(nadd == 0){
resultcontent_sendout = "&#x"+content_sendout.substring(nadd*i, (nadd*i)+i) + ";&#x";
}else if(nadd == lengthwelcomemsg-1){
resultcontent_sendout += content_sendout.substring(nadd*i, (nadd*i)+i) + ";";
}else{
resultcontent_sendout += content_sendout.substring(nadd*i, (nadd*i)+i) + ";&#x";
}
}
return resultcontent_sendout;
}

Java - Reverse String null error

The input is meant to appear like this, example.
\n
Kazan R
\n
6789
\n
Nzk462
\n
However the output I receive looks like this
kzn462nullnzk
Why is this? and How can i solve it?
private void btnGenerateActionPerformed(java.awt.event.ActionEvent evt) {
secondname = JOptionPane.showInputDialog("Enter your surname:");
firstname = JOptionPane.showInputDialog("Enter your firstname:");
idno = JOptionPane.showInputDialog("Enter your idno:");
nametag = firstname.substring(0, 1);
initials = secondname + " " + nametag;
int randnum;
do {
randnum = (int) (Math.random() * 900) + 100;
} while (randnum % 2 != 0);
code = secondname.replaceAll("[aeiou || AEIOU](?!\\b)", "")+randnum ;
txaDisplay.append(initials + '\n' + idno.substring(6,10) + '\n' + code);
int length = secondname.length();
for (int i = length - 1; i >= 0; i--) {
reverse = reverse + secondname.charAt(i);
}
String end = reverse + code;
txaDisplay.append( reverse);
Why don't you use
new StringBuilder(secondname).reverse().toString()
to reverse your String? It's better, simple and more maintanable.
Get the character array from your source string
Create a new char array of same length
Start iterating from 0 to (sourceStringLength-1)
In each iteration, get the last character
from the end in your source array and populate in your new array
Create a new string from this new array
String source = "abcdefg";
char[] chars = source.toCharArray();
char[] reverseChars = new char[source.length()];
int len = source.length();
for(int i= 0; i < len; i++){
reverseChars[i] = chars[len-1-i];
}
String reverse = new String(reverseChars);
System.out.println(reverse);
Since You don't want to use StringBuilder/StringBuffer.
Try this
String reversedString="";
for(int i=inputString.length-1;i>=0;){
reversedString+=inputString.charAt(i--);
}
I think the problem is your definition of reverse, maybe you have something like:
String reverse;
Then you don't initialize your "reverse" so when your program makes the first concatenation in your loop, it looks like this:
reverse = null + secondname.charAt(i);
The null value is converted to a string so it can be visible in the output.
I hope this information helps you.
Good Luck.

How to start replacing characters at some point?

It was very hard to form the question and I am sure it is still not clear.
I have a CSV file e.g.: Firstname;Lastname;Adress;product1;product2;product3;product4;
I would like to start replacing ";" with "::". The problem is, I want to start replacing after third semicolon.
I know it can be done in while loop where I check every character, when semicolon occurs I will count +1 and if counter is 3, I will start replacing. But isn't there a way how to do it without a loop?
You can use indexOf(char,fromIndex) method.
Your third semicolon position search can be inlined :
csvLine.indexOf(';', csvLine.indexOf(';', csvLine.indexOf(';') + 1) + 1)
We assume that our csvLine has a least 3 semi-colons...
String csvLine = "Firstname;Lastname;Adress;product1;product2;product3;product4";
//Index of "fromIndex" param is inclusive, that's why we need to add 1
int pos = csvLine.indexOf(';', csvLine.indexOf(';', csvLine.indexOf(';') + 1) + 1);
//Retrieve string from the char after the third semi-colon
String truncatedLine = csvLine.substring(pos + 1);
//Replace ";" by "::" on our substring
truncatedLine = truncatedLine.replaceAll(";", "::");
//Then concat the first part of csvLine with the second
String result = csvLine.substring(0, pos + 1).concat(truncatedLine);
System.out.println(result); //Print => Firstname;Lastname;Adress;product1::product2::product3::product4
Poor input control and performance but we don't have any loops :)
If I have understood what you want, try this.
First search se position of the third semicolon:
String csvContent = "Firstname;Lastname;Adress;product1;product2;product3;product4;";
int i = 0;
int index= 0;
while(i < 4){
index = csvContent.indexOf(';', (index + 1));
i++;
}//index = position of the thrid semicolon
Second, cut your CSV content at the index position.
String tmp1 = csvContent.substring(0, index);
String tmp2 = csvContent.substring(index, csvContent.length());
Thrid, replace all ';' by '::':
tmp2 = tmp2.replaceAll(";", "::");
Finaly, rebuild your file content:
csvContent = tmp1 + tmp2;
int i = 0;
int pos = 0;
while (i < 3) {
pos = string.indexOf(';', pos+1);
i++;
}
String newString = string.substring(0, pos) +";"+ (string.substring(pos + 1, string.length()).replace(";", "::"));
how about a regex solution?
Pattern pattern = Pattern.compile("(.*?;.*?;.*?;)(.*)");
Matcher match = pattern.matcher(str);
if(match.matches()) {
String firstThree = match.group(1);
String rest = match.group(2);
rest = rest.replace(";", "::");
return firstThree + rest;
}

How do you add a newline character in a string at specific indices?

I have a string:
String testString= "For the time being, programming is a consumer job, assembly line coding is the norm, and what little exciting stuff is being performed is not going to make it compared to the mass-marketed cräp sold by those who think they can surf on the previous half-century's worth of inventions forever"
like this: For the time being, programmi \n........\n.......\n
After each length of 20 characters in this string, I want to put a newline character \n for display in a TextView in Android.
You must have to use regex for achieve your task its fast and efficient. Try below code:-
String str = "....";
String parsedStr = str.replaceAll("(.{20})", "$1\n");
The (.{20}) will capture a group of 20 characters. The $1 in the second will put the content of the group. The \n will be then appended to the 20 characters which have been just matched.
How about something like that?
String s = "...whateverstring...";
for(int i = 0; i < s.length(); i += 20) {
s = new StringBuffer(s).insert(i, "\n").toString();
}
I know there is a technically better solution to use a StringBuffer and the insert method for that class, or even regex, but I'll show you a different algorithmic approach using String#substring:
String s = "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
int offset = 0; // each time you add a new character, string has "shifted"
for (int i = 20; i + offset < s.length(); i += 20) {
// take first part of string, add a new line, and then add second part
s = s.substring(0, i + offset) + "\n" + s.substring(i + offset);
offset++;
}
System.out.println(s);
The result is this:
12345678901234567890
12345678901234567890
12345678901234567890
12345678901234567890
12345678901234567890
1234567890123456789
StringBuilder sb = new StringBuilder();
int done = 0;
while( done < s.length() ){
int todo = done + 20 < s.length() ? 20 : s.length() - done;
sb.append( s.substring( done, done + todo ) ).append( '\n' );
done += todo;
}
String result = sb.toString();
This also appends a newline at the end, but you can modify it easily to avoid that.

Getting the last integer from a string

Say I have a string 3 + 4 = 7 or 23 - 4 = 19. I'm wondering how I would go about getting the last integer from the string so that it can be compared to another int.
Ive used this code:
int first = Integer.parseInt(str.substring(0, str.indexOf(" ")));
int second = Integer.parseInt(result.substring(result.indexOf('+')+1 , result.indexOf('=')));
to get the first and second integers for computation, but I can't seem to get the last integer in string when I'm using the method above. Is it just something I'm doing wrong or is there something else I need to do?
I also cannot use arrays, regex, try/catch, or a SystemTokenizer.
And my strings will not always be in the a + b = c format with the spaces or a single digit integer.
the strings are taken from a text file that is imported by the scanner. Here's a sample of the equations in the file:
11 - 2 = 9
12 - 1 = 11
7 + 1 = 8
7 - 3 = 4
7 + 2 = 9
14 + 4 = 18
If all of your strings are in this format - a + b = c, then there is a simple way -
String[] parts = str.split("=");
String lastDigit = parts[parts.length - 1].trim();
int last = Integer.parseInt(lastDigit);
Check out the docs.
Update
As per your requirement of not wanting to use regex, you can do something like this -
public int getLastDigit(String expression) {
StringBuffer result = new StringBuffer();
for (int i = expression.length() - 1; i >= 0; i--) {
char c = expression.charAt(i);
if (c == '=') {
break;
}
else {
result.append(c);
}
}
return Integer.parseInt(result.reverse()
.toString()
.trim());
}
int last = getLastDigit("1 + 3 = 14");
System.out.println(last); // will print 14
This will work a lot easier:
String[] tokens = str.Split(" ");
int first = Integer.parseInt(tokens[0]);
int second = Integer.parseInt(tokens[1]);
int last = Integer.parseInt(tokens[3]);
Otherwise without arrays, use lastIndexOf:
int last = Integer.parseInt(str.substring(str.lastIndexOf(" "), str.length()));
simple use split and get index[1] to get last integer in string
just split with "="
Does this work?
int last = Integer.parseInt(str.substring(str.indexOf("=") + 1, str.length));
The idea is to get the index of the "=", and then parse the substring of there to the end.
I did "str.indexOf("=") + 1" so that it didn't include the "sign".
String [] tokens = str.split("=");
String finalDigit = tokens[tokens.length-1];
You would need trim the extracted digit, other wise it is possible to throw
Exception in thread "main" java.lang.NumberFormatException: For input
string: " 7"
To extract the last digit, you may follow the below code
String str1="3 + 4 = 7";
String str2= str1.substring(str1.lastIndexOf("=")+1).trim();
int i = Integer.parseInt(str2);
import java.io.*;
class GetString{
publice static void main(String []args)
{
string str,int x;
Scanner s = new Scanner(input).useDelimiter("\n"); //take each line
while((str=s.next())!=NULL)
{
str.trim();
int first = Integer.parseInt(str.substring(0, str.indexOf(" ")));
//Depending on weather the sign is '+' or '-' it will take the index of that
int second = Integer.parseInt(str.substring((x=str.indexOf('+')>-1?
str.indexOf('+'):str.indexOf('-'))+1 , result.indexOf('=')));
int Third= Integer.parseInt(str.substring(str.indexOf("="), str.Length-1))
}
s.close();
}
}
Its a general idea not a perfect code.Edits and suggestions are welcome.

Categories

Resources