What I want to do is getting the first 2 digits of a number. If number hasn't digits more than 1 then It will add leading zeros.
s variable equals to "122" but I want to get first 2 digits which are "12". I think there is a problem with my format.
for example if totalNumberOfCars equals 6 then s variable will equals to "06".
int totalNumberOfCars = 122;
String s = String.format("%02d", (totalNumberOfCars + 1))
EDIT: Is there anyone knows what String.format("%02d", totalNumberOfCars) does?
I'm afraid that String.format() won't do the job, see http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax.
But your format string will be a good starting point for a substring since any ifs are unnecessary:
int totalNumberOfCars = 122;
String s = String.format("%02d", (totalNumberOfCars + 1));
s = s.substring(0,2);
By the way the condensed explaination from the javadoc link above:
The format specifiers which do not correspond to arguments have the following syntax:
%[flags][width]conversion
[...] further down on the same page:
Flags
'0' [...] [means] zero-padded
[...] further down on the same page:
Width
The width is the minimum number of characters to be written to the output. For the line separator conversion, width is not applicable; if it is provided, an exception will be thrown.
Example output would be:
1 --> 01
-1 --> -1
10 --> 10
122--> 122
Maybe not very elegant, but it should work:
String s = ((totalNumberOfCars<10?"0":"")+totalNumberOfCars).substring(0,2);
String s = substring_safe (s, 0, 2);
static String substring_safe (String s, int start, int len) { ... }
which will check lengths beforehand and act accordingly (either return smaller string or pad with spaces).
Related
I am obviously new to java. I have this assignment where I am supposed to write a program which performs arithmetic operations on numbers expressed as a character string.
I don't know where to start. I have tried googling, looking through my book, big java, in the relevant sections but can't seem to find helpful information.
I found a program that have completed the same assignment but I want to learn write my own and understand how to go about.
I can show you one of the methods that he used.
I have bolded a few comments where I get confused.
public static String add(String num1, String num2) {
while (num1.length() > num2.length()) {
num2 = "0" + num2;
}
while (num1.length() < num2.length()) {
num1 = "0" + num1;
}
int carry = 0; // whats the point of this?
String result = "";
// look at the for loop bellow. I don't understand why he is converting the strings to ints this
// way? this doesn't even return the correct inputed numbers?
for (int i = 1; i <= num1.length(); i++) {
int digit1 = Character.getNumericValue(num1.charAt(num1.length() - i));
int digit2 = Character.getNumericValue(num2.charAt(num2.length() - i));
int sum = digit1 + digit2 + carry;
carry = sum / 10;
result = (sum % 10) + result;
// why is he dividing the sum with 10? If the user inputs a 5, would't the result become 0.5
// which isn't a valid int value? this line is also confusing
}
if (carry > 0) {
result = carry + result;
}
return result;
}
Any explanation or even guidance to a page where I am trying to do is explained would be very appreciated.
I found a program that have completed the same assignment but I want to learn write my own and understand how to go about.
That is the right idea. I suggest that you stop looking at the code that you found. (I'm sure that your teachers don't want you to look up the answers on the internet, and you will learn more from your homework if you don't do it.)
So how to proceed?
(I am assuming that you are supposed to code the methods to do the arithmetic, and not just convert the entire string to a primitive number or BigInteger and use them to do the arithmetic.)
Here's my suggested approach:
What you are trying to program is the equivalent of doing long addition with a pencil and paper. Like you were taught in primary school. So I suggest that you think of that pencil-and-paper procedure as an algorithm and work out how to express it as Java code. The first step is to make sure that you have the steps of this algorithm clearly in your head.
Try to break the larger problem into smaller sub-problems. One sub-problem could be how to convert a character representing a decimal digit into an integer; e.g. how to convert '1' to 1. Next sub-problem is adding two numbers in the range 0 to 9 and dealing with the "carry". A final sub-problem is converting an integer in the range 0 to 9 into the corresponding character.
Write sample Java code fragments for each sub-problem. If you have been taught about writing methods, some of the code fragments could be expressed as Java methods.
Then you assemble the solutions to the sub-problems into a solution for the entire problem. For example, adding two (positive!) numbers represented as strings involves looping over the digits, starting at the "right hand" end.
As part of your program, write a collection of test cases that you can use to automate the checking. For example:
String test1 = add("8", "3");
if (!test1.equals("11")) {
System.out.println("test1 incorrect: expected '11' go '" +
test1 + "'");
}
Hints:
You can "explode" a String to a char[] using the toCharArray method. Or you could use charAt to get characters individually.
You can convert between a char representing a digit and an int using Character methods or with some simple arithmetic.
You can use + to concatenate a string and a character, or a character and a string. Or you can use a StringBuilder.
If you need to deal with signed numbers, strip off and remember the sign, do the appropriate computation, and put it back; e.g. "-123 + -456" is "- (123 + 456)".
If you need to do long multiplication and long division, you can build them up from long addition and long subtraction.
You can convert a number in String format to a number in numeric format by “long n = Long. parseLong(String)” or “Long n = Long.valueOf(String)”. Then just add 2 long variables using a + sign. It will throw NumberFormatException if the String is not a number but a character. Throw that exception back to the caller.
The first part of the code pads both numbers to equal lengths.
e.g. "45" + "789" will be padded to "045" + "789"
The for loop evaluates one character at a time, starting from the right hand most.
iteration 1 -> (right most)
5 + 9 -> 14
when you divide an integer with another integer, you will always get an integer.
hence carry = 14/10 = 1 (note: not 1.4, but 1, because an int cannot have decimal places)
and the remainder is 14 % 10 = 4 (mod operation)
we now concatenate this remainder into "result" (which is "" empty)
result = (14%10)+ result; // value of result is now "4"
iteration 2 -> (second right most)
4+8 + (carry) = 4 + 8 + 1 = 13
same thing, there is a carry of 13/10 = 1
and the remainder is 13%10 = 3
we concatenate the remainder into result ("4")
result = (13%10) + result = 3 +"4" = "34"
iteration 3->
0 + 7 + 1 = 8
this time 8/10 will give you 0 (hence carry = 0)
and 8%10 will give a remainder of 8.
result = 8 + "34" = "834"
after all the numbers have been evaluated, the code checks if there are anymore carry. if the value is more than 0, then that value is added to the front of the result.
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, " "));
I want to display the length of a 4-digit number displayed by the user, the problem that I'm running into is that whenever I read the length of a number that is 4-digits long but has trailing zeros the length comes to the number of digits minus the zeros.
Here is what I tried:
//length of values from number input
int number = 0123;
int length = (int)Math.log10(number) + 1;
This returns to length of 3
The other thing I tried was:
int number = 0123;
int length = String.valueOf(number).length();
This also returned a length of 3.
Are there any alternatives to how I can obtain this length?
Because int number = 0123 is the equivalent of int number = 83 as 0123 is an octal constant. Thanks to #DavidConrad and #DrewKennedy for the octal precision.
Instead declare it as a String if you want to keep the leading 0
String number = "0123";
int length = number.length();
And then when you need the number, simply do Integer.parseInt(number)
Why is the syntax of octal notation in java 0xx ?
Java syntax was designed to be close to that of C, see eg page 20 at
How The JVM Spec Came To Be keynote from the JVM Languages Summit 2008
by James Gosling (20_Gosling_keynote.pdf):
In turn, this is the way how octal constants are defined in C language:
If an integer constant begins with 0x or 0X, it is hexadecimal. If it
begins with the digit 0, it is octal. Otherwise, it is assumed to be
decimal...
Note that this part is a C&P of #gnat answer on programmers.stackexchange.
https://softwareengineering.stackexchange.com/questions/221797/reasoning-behind-the-syntax-of-octal-notation-in-java
Use a string instead:
String number = "0123";
int length = number.length(); // equals 4
This doesn't work with an int, as the internal representation of 0123 is identical to 123. The program doesn't remember how the value was written, only the actual value.
What you can do is declare a string:
String number = "0123";
int numberLengthWithLeadingZeroes = number.length(); // == 4
int numberValue = Integer.parseInt(number); // == 123
If you really want to include leading 0's you could always store it in an array of of characters
example:
char[] abc = String.valueOf(number).toCharArray();
Then obviously you can figure out the length of the array.
As several people have pointed out already though, integers don't have leading 0's.
String abc=String.format("%04d", yournumber);
for zero-padding with length=4.
Refer to this link .
http://download.oracle.com/javase/7/docs/api/java/util/Formatter.html
this might help u ..
Integers in Java don't have leading zeroes. If you assign the value 0123 to your int or Integer variable, it will be interpreted as an octal constant rather than a decimal one, which can lead to subtle bugs.
Instead, if you want to keep leading zeroes, use a String, e.g.
String number = "0123";
This way you can also measure the length:
String number = "0123";
System.out.println(number.length());
Integer.toBinaryString(data)
gives me a binary String representation of my array data.
However I would like a simple way to add leading zeros to it, since a byte array equal to zero gives me a "0" String.
I'd like a one-liner like this:
String dataStr = Integer.toBinaryString(data).equals("0") ? String.format(format, Integer.toBinaryString(data)) : Integer.toBinaryString(data);
Is String.format() the correct approach? If yes, what format String should I use?
Thanks in advance!
Edit: The data array is of dynamic length, so should the number of leading zeros.
For padding with, say, 5 leading zeroes, this will work:
String.format("%5s", Integer.toBinaryString(data)).replace(' ', '0');
You didn't specify the expected length of the string, in the sample code above I used 5, replace it with the proper value.
EDIT
I just noticed the comments. Sure you can build the pattern dynamically, but at some point you have to know the maximum expected size, depending on your problem, you'll know how to determine the value:
String formatPattern = "%" + maximumExpectedSize + "s";
This is what you asked for—padding is added only when the value is zero.
String s = (data == 0) ? String.format("%0" + len + 'd', 0) : Integer.toBinaryString(data);
If what you really want is for all binary values to be padded so that they are the same length, I use something like this:
String pad = String.format("%0" + len + 'd', 0);
String s = Integer.toBinaryString(data);
s = pad.substring(s.length()) + s;
Using String.format() directly would be the best, but it only supports decimal, hexadecimal, and octal, not binary.
You could override that function in your own class:
public static String toBinaryString(int x){
byte[] b = new byte[32]; // 32 bits per int
int pos = 0;
do{
x = x >> 1; // /2
b[31-pos++] = (byte)(x % 2);
}while(x > 0);
return Arrays.toString(b);
}
would this satisfy your needs?
String dataStr = data == 0 ? "00" + Integer.toBinaryString(data) : Integer.toBinaryString(data);
edit: noticed the comment about dynamic length:
probably some of the other answers are more suited:)
This, in concept, is almost same as #Óscar López answer, but different methods are used, so i thought i should post it. Hope this is fine.
1] Building the format string
String format = "%0" + totalDigits + "d";
2] Integer to Binary Conversion
String dataStr = Integer.toBinaryString(data);
3] Padding with Leading Zeros
dataStr = String.format(format, new Integer(dataStr));
The major difference here is the 3rd step. I believe, its actually a hack.
#erickson is right in String.format() not supporting binary, hence, i converted the binary number to an integer (not its equivalent), i.e., "100" will be converted to hundred (100), not four(4). I then used normal formatting.
Not sure about how much optimized this code is, but, i think its more easy to read, but, maybe, its just me.
EDIT
1] Buffer Over-run is possible for longer binary strings. Long can be used, but, even that has limitations.
2] BigInteger can be used, but, I'm sure, it will be the costliest at runtime compared to all the other methods.
So, it seems, unless only shorter binary strings are expected, replace() is the better method.
Seniors,
please correct me if I'm wrong.
Thanks.
This question already has answers here:
How can I pad an integer with zeros on the left?
(18 answers)
Closed 8 years ago.
Is there a better way of getting this result? This function fails if num has more digits than digits, and I feel like it should be in the library somewhere (like Integer.toString(x,"%3d") or something)
static String intToString(int num, int digits) {
StringBuffer s = new StringBuffer(digits);
int zeroes = digits - (int) (Math.log(num) / Math.log(10)) - 1;
for (int i = 0; i < zeroes; i++) {
s.append(0);
}
return s.append(num).toString();
}
String.format (https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html#syntax)
In your case it will be:
String formatted = String.format("%03d", num);
0 - to pad with zeros
3 - to set width to 3
Since Java 1.5 you can use the String.format method. For example, to do the same thing as your example:
String format = String.format("%0%d", digits);
String result = String.format(format, num);
return result;
In this case, you're creating the format string using the width specified in digits, then applying it directly to the number. The format for this example is converted as follows:
%% --> %
0 --> 0
%d --> <value of digits>
d --> d
So if digits is equal to 5, the format string becomes %05d which specifies an integer with a width of 5 printing leading zeroes. See the java docs for String.format for more information on the conversion specifiers.
Another option is to use DecimalFormat to format your numeric String. Here is one other way to do the job without having to use String.format if you are stuck in the pre 1.5 world:
static String intToString(int num, int digits) {
assert digits > 0 : "Invalid number of digits";
// create variable length array of zeros
char[] zeros = new char[digits];
Arrays.fill(zeros, '0');
// format number as String
DecimalFormat df = new DecimalFormat(String.valueOf(zeros));
return df.format(num);
}
How about just:
public static String intToString(int num, int digits) {
String output = Integer.toString(num);
while (output.length() < digits) output = "0" + output;
return output;
}
In case of your jdk version less than 1.5, following option can be used.
int iTest = 2;
StringBuffer sTest = new StringBuffer("000000"); //if the string size is 6
sTest.append(String.valueOf(iTest));
System.out.println(sTest.substring(sTest.length()-6, sTest.length()));