Integer to Alphanumeric string conversion - java

I need to convert five digit integer to alphanumeric string of length 5.Doing below but sometimes it doesn't provide alphanumeric but numeric value.
Long x = 12345L;
String code = Long.toHexString(x).toUpperCase();
I want to get Alphanumeric string of length 5 always.

Try this
static String alphaNumric(int value) {
String s = "abcde" + Integer.toString(value, 36);
return s.substring(s.length() - 5);
}
and
int[] tests = { 12345, 1, 36, 36 * 36, 32767, 99999 };
for (int i : tests)
System.out.println(i + " -> " + alphaNumric(i));
output
12345 -> de9ix
1 -> bcde1
36 -> cde10
1296 -> de100
32767 -> depa7
99999 -> e255r

That's hardly surprising.
For example, 0x12345 is 74565, so 74565 does not contain any of the digits A to F when converted to hexadecimal.
Given that 99999 is 0x1869F, you have plenty of room in your converted string to accommodate some "junk" data, consider introducing an additive constant (0xA0000 perhaps which at least guarantees at least one alpha character for positive inputs), or even a number that your XOR with your original.

Related

How to set width AND pad integer witdth String Formatter in Java

Given I have the following integers:
1, 10, 100
I want to pad them with zeroes to have exactly 3 digits:
001
010
100
and I want to print them prefixed by 10 spaces:
001 //assume 10 spaces from the beginning of the line
010
100
I want to use Java formatter string to accomplish this but am only successful in accomplishing one of the above mention conditions but not both at once.
Below are 2 expressions that I created that accomplish each one of these conditions:
#Test
public void test1() {
String[] langs = { "TEXTX", "TEXTXXX", "TEXTXX" };
int[] nums = {1, 10, 100};
for (int i = 0; i < 3; i++) {
String s = langs[i];
int n = nums[i];
System.out.printf("%1$s%2$14s%3$03d\n", s, " ", n);
}
}
According to documentation the formatter string has the below form:
%[argument_index$][flags][width][.precision]conversion
but apparently the zero padding flag parameter cannot be followed by width parameter as it is being parsed as one number resulting in a "long width".
How can this be rewritten to accomplish the above mentioned conditions?
NOTE:
My only idea was to explicitly add a single space to the arguments and try to manipulate it as an argument. Something like this:
System.out.printf("%1$s%2$10s%3$03d\n", s, " ", n);
EDIT:
My apologies, I just realized that I didn't fully described my question. These numbers need to follow certain other strings of different length, like this:
textX 001
textXXX 010
textXX 100
So that the spacing is variable.
If the two only criterias are the padding of 10 Spaces and zero-padding of the numbers:
final String str = String.format("%10s%03d", " ", 2);
Edit after update from OP:
System.out.printf("%-10s%03d", "abc", 2);
How it Works:
We need two arguments for Our pattern, one for the String of length 10, and one for the integer.
%10s is a pattern for a String of length 10. In order to left align it, we add the -: %-10s. The second argument is the integer of length 3 that we want to left pad With zero: %03d.
If we dont want to rearrange or reuse an argument for multiple format specifiers, just pass the arguments in the order specified in the pattern.
This answer is based on your latest edit, which revealed this data:
textX 001
textXXX 010
textXX 100
Assuming that the second column always has a width of 3, then your problem distills down to figuring out how many spaces need to be added after the first text column. Here is how you could do this in Java 7:
String text = "textXXX";
int n = 10 - text.length();
String padding = String.format("%0" + n + "d", 0).replace("0", " ");
In Java 8 you could this to get the padding string:
String padding = String.join("", Collections.nCopies(n, " "));

Convert int which start with leading zero to string

I'm trying to convert int's which start with 0 to strings to be stored in a phone directory as the telephone numbers can start with 0.
I've tried -
int num = 0125;
String.format("%04d",num);
and
Integer.toString(num);
and
DecimalFormat df = new DecimalFormat("0000");
df.format(num);
Each time I get the output 0085 rather than 0125.
How do I convert an int with a leading zero to a string in decimal format?
An int value starting with a zero is considered to be a octal number (having numbers from 0 - 7) similar to hexadecimal numbers. Hence your value:
0125
is equal to: 1 * 82 + 2 * 81 + 5 * 80 == 64 + 16 + 5 == 85
Don't try to represent a phone-number as an int. Instead use a String and validate it using a regex expression. If you combine both, you may as well represent a phone number by its own type like:
public class PhoneNumber {
private final String number;
public PhoneNumber(String number) {
if (number == null || !number.matches("\\d+([-]\\d+)?")) {
throw new .....
}
this.number = number;
}
}
The regex is just an example matching phone numbers like: 1234 or 0123-45678.
A numeric literal that starts with 0 is considered to be Octal (base 8). 125 base 8 is 85 base 10 (decimal).
Also, int i = 09 will throw a compiler error for the same reason.
See 09 is not recognized where as 9 is recognized
0125 is actually 85. Why?
Numbers that starts with 0, are octal numbers. So 0125 is:
5*80 + 2*81 + 1*82 = 85
See the JLS - 3.10.1. Integer Literals:
An octal numeral consists of an ASCII digit 0 followed by one or more
of the ASCII digits 0 through 7 interspersed with underscores, and can
represent a positive, zero, or negative integer.

BigInteger to String according to ASCII

Is there a way to convert a series of integers to a String according to the ASCII table. I want to take the ASCII value of a String and convert it back to a String. For example,
97098097=> "aba"
I really need an effective way of taking an integer and converting it to a String according to its ASCII value. This method must also take into account the fact that there is no zero in front of the '9' when the String "aba" has an ASCII value of 97098097 as 'a' has an ASCII value of 097 and a String "dee" has one of 100101101. This means that not every number will have an ASCII value that has a number of digits that is a multiple of three.
If you have any misunderstandings of what I'm trying to do please let me know.
No lookup table required.
while (string.length() % 3 != 0)
{
string = '0' + string;
}
String result = "";
for (int i = 0; i < string.length(); i += 3)
{
result += (char)(Integer.parseInt(string.substring(i, i + 3)));
}
First, I would create some sort of lookup table in your code with all the ascii values and their String equivalent. Then take the big int and convert it to a String. Then do the mod of 3 with the length of your bigint string to determine if you need to add 1, 2, or no 0's to the front of it. Then just grab every 3 integers from the front of the number, compare it to the lookup table, and append the corresponding value to your result string.
Example:
Given 97098097
You would convert it to: "97098097"
Then you do a mod with 3 resulting in a value of 1, so 1 zero needs to be added.
Append 1 zero: "097098097"
Then grab every 3 from the front and compare to look up table:
097 -> a, so result += "a"
098 -> b, so result += "b"
097 -> a, so result += "a"
You end with result being "aba"

Java: charAt convert to int?

I would like to key in my nirc number e.g. S1234567I and then put 1234567 individualy as a integer as indiv1 as charAt(1), indiv2 as charAt(2), indiv as charAt(3), etc. However, when I use the code below, I can't seem to get even the first number out? Any idea?
Scanner console = new Scanner(System.in);
System.out.println("Enter your NRIC number: ");
String nric = console.nextLine();
int indiv1 = nric.charAt(1);
System.out.println(indiv1);
You'll be getting 49, 50, 51 etc out - those are the Unicode code points for the characters '1', '2', '3' etc.
If you know that they'll be Western digits, you can just subtract '0':
int indiv1 = nric.charAt(1) - '0';
However, you should only do this after you've already validated elsewhere that the string is of the correct format - otherwise you'll end up with spurious data - for example, 'A' would end up returning 17 instead of causing an error.
Of course, one option is to take the values and then check that the results are in the range 0-9. An alternative is to use:
int indiv1 = Character.digit(nric.charAt(1), 10);
This will return -1 if the character isn't an appropriate digit.
I'm not sure if this latter approach will cover non-Western digits - the first certainly won't - but it sounds like that won't be a problem in your case.
Take a look at Character.getNumericValue(ch).
try {
int indiv1 = Integer.parseInt ("" + nric.charAt(1));
System.out.println(indiv1);
} catch (NumberFormatException npe) {
handleException (npe);
}
tl;dr
The modern solution uses Unicode code point numbers rather than the outmoded char type.
Here is an IntStream, a successive stream of each character’s code point number, printing each of those numbers to console:
"S1234567I"
.codePoints()
.forEach( System.out :: println )
83
49
50
51
52
53
54
55
73
Show each character along with its code point number. To convert a code point number back into a character, call Character.toString while passing the integer: Character.toString( codePoint ).
String s = Character.toString( 49 ) ; // Returns "1".
…and…
String s = Character.toString( 128_567 ) ; // Returns "😷" FACE WITH MEDICAL MASK.
Example:
"S1234567I".codePoints().forEach( ( int codePoint ) -> {
String message = Character.toString( codePoint ) + " → " + codePoint;
System.out.println( message );
} );
S → 83
1 → 49
2 → 50
3 → 51
4 → 52
5 → 53
6 → 54
7 → 55
I → 73
Unicode code point
The char type is obsolete, unable to represent even half of the 143,859 characters defined in Unicode. The char type is a 16-bit number underneath, capable of representing a range of numbers of about ± 64,000. Unicode characters are assigned numbers along a range of about a million, too big for char to handle.
Instead, use Unicode code point integer numbers to represent individual characters.
We can get a stream of int primitive values (IntStream) from a string, each number representing the Unicode code point of each successive character.
IntStream intStream = "S1234567I".codePoints() ;
Process each code point number. Here we simply print each number.
intStream.forEach( System.out :: println );
When run.
83
49
50
51
52
53
54
55
73
Or perhaps you want an array of the int numbers.
int[] codePoints = "S1234567I".codePoints().toArray();
Dump to console.
System.out.println( "codePoints = " + Arrays.toString( codePoints ) );
codePoints = [83, 49, 50, 51, 52, 53, 54, 55, 73]
Or perhaps you want a List object containing all those code point numbers. Here is a non modifiable list made by List.of. We call boxed to invoke auto-boxing feature to convert int primitives into Integer objects. Then a Collector implementation gathers the output of the stream into a List.
List < Integer > codePoints = "S1234567I".codePoints().boxed().collect( Collectors.toList() );
Explaining those parts:
List < Integer > codePoints = // Desired result is a `List` collection of `Integer` objects.
"S1234567I" // Your input string.
.codePoints() // Generate an `IntStream`, a succession of `int` integer numbers representing the Unicode code point number of each character in the `String` object.
.boxed() // Convert each `int` primitive to an `Integer` object.
.collect( // Collect the produced `Integer` objects together.
Collectors.toList() // Specify a `Collector` implementation that knows how to make a `List` object, containing our `Integer` objects.
) // Returns a `List` of `Integer` objects.
;
Pull digits
Perhaps you want to filter out the alphabetic characters to leave only the digits found in your input string. The Character class offers tests such as isDigit.
For an input of "S1234567I", that means dropping the S and the I, leaving 1234567, producing the integer number 1,234,567.
List < Integer > codePointsOfDigitsFromInput = "S1234567I".codePoints().filter( ( int codePoint ) -> Character.isDigit( codePoint ) ).boxed().collect( Collectors.toList() );
Break that out to multiple lines.
List < Integer > codePointsOfDigitsFromInput =
"S1234567I"
.codePoints()
.filter(
( int codePoint ) -> Character.isDigit( codePoint )
)
.boxed()
.collect( Collectors.toList() );
codePointsOfDigitsFromInput = [49, 50, 51, 52, 53, 54, 55]
We can modify that code to generate a String containing only digits taken from that input. See Question, Make a string from an IntStream of code point numbers?. And then we make an int integer number of that text.
String numberComponentFromInput =
"S1234567I"
.codePoints()
.filter(
( int codePoint ) -> Character.isDigit( codePoint )
)
.collect( // Collect the results of processing each code point.
StringBuilder :: new , // Supplier<R> supplier
StringBuilder :: appendCodePoint , // ObjIntConsumer<R> accumulator
StringBuilder :: append // BiConsumer<R,​R> combiner
)
.toString();
int x = Integer.valueOf( numberComponentFromInput );
numberComponentFromInput = 1234567
x = 1234567
I know question is about char to int but this worth mentioning because there is negative in char too ))
From JavaHungry you must note the negative numbers for integer
if you dont wana use Character.
Converting String to Integer : Pseudo Code
1. Start number at 0
2. If the first character is '-'
Set the negative flag
Start scanning with the next character
For each character in the string
Multiply number by 10
Add( digit number - '0' ) to number
If negative flag set
Negate number
Return number
public class StringtoInt {
public static void main (String args[])
{
String convertingString="123456";
System.out.println("String Before Conversion : "+ convertingString);
int output= stringToint( convertingString );
System.out.println("");
System.out.println("");
System.out.println("int value as output "+ output);
System.out.println("");
}
public static int stringToint( String str ){
int i = 0, number = 0;
boolean isNegative = false;
int len = str.length();
if( str.charAt(0) == '-' ){
isNegative = true;
i = 1;
}
while( i < len ){
number *= 10;
number += ( str.charAt(i++) - '0' );
}
if( isNegative )
number = -number;
return number;
}
}
int indiv1 = Integer.parseInt(nric.charAt(1));

Why are integer literals with leading zeroes interpreted strangely?

This prints 83
System.out.println(0123)
However this prints 123
System.out.println(123)
Why does it work that way?
A leading zero denotes that the literal is expressed using octal (a base-8 number).
0123 can be converted by doing (1 * 8 * 8) + (2 * 8) + (3), which equals 83 in decimal.
For some reason, octal floats are not available.
Just don't use the leading zero if you don't intend the literal to be expressed in octal.
There is also a 0x prefix which denotes that the literal is expressed in hexadecimal (base 16).
Because integer literals starting with 0 are treated as octal numbers.
See section 3.10.1 of the JLS
Try this:
public static String leftPad(int n, int padding) {
return String.format("%0" + padding + "d", n);
}
leftPad(5, 3); // return "005"
leftPad(15, 5); // return "00015"
leftPad(224, 3); // return "224"
leftPad(0, 4); // return "0000"
first one printed as 83 because java takes 0123 as octal number and it prints decimal equivalent of that number.
The octal (leading 0) and hexadecimal (leading 0x) were inherited from C.
For comparison, try
System.out.println(0x123);
In Java integer literals with a leading zero are octal integers (base 8).
(1 * 8^2) + (2 * 8^1) + (3 * 8^0) = 83
So do not use any number leading with 0 if you don't want to treat it as an octal number.
0123 -> 83
1010L -> 1010
0101L -> 65
The numbers 1010L and 0101L are not in binary representation (just to avoid the confusion).
These numbers are in decimal representation.
Even as per the Regex patterns in Oracle docs,
\0n is the character with octal value 0n (0 <= n <= 7)
\xhh is the character with hexadecimal value 0xhh
Thus, your number 0101 be it in Integer or Long format is treated as an Octal representation of a number.
123 => 1 * 8^2 + 2 * 8^1 + 1 * 8^0 = 83
0101 => 1 * 8^2 + 0 * 8^1 + 1 * 8^0 = 64 + 0 + 1 = 65
printf will do it: http://java.sun.com/developer/technicalArticles/Programming/sprintf/
public class X
{
public static void main(final String[] argv)
{
System.out.printf("%04d", 123);
System.out.println();
}
}
You could also make it "%0" + size + "%d" if you wanted to vary the length... though if the lengths were common I'd probably make constants like "%04d", "%012d", etc...

Categories