Code is supposed to do this: Return the number of times that the string "code" appears anywhere in the given string, except we'll accept any letter for the 'd', so "cope" and "cooe" count.
The problem: Ran across Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 11 (line number:10)
public int countCode(String str){
int a = 0; // counter goes thru string
int b = str.length()-1;
int counter = 0; //counts code;
if(str.length() < 4) return 0;
else{
while (a <=b){
if(str.charAt(a) == 'c'){
if(str.charAt(a+1) == 'o'){
if(str.charAt(a+3) == 'e'){
counter++;
a= a+3;
} // checks e
else a++;
} // checks o
else a++;
} // checks c
else a++;
}
return counter;
}
}
Here's what I tried to evaluate to get said exception:
countCode("xxcozeyycop") --> EXPECTED RESULT 1
countCode("cozcop") --> EXPECTED RESULT
Your loop goes from 0 to the length of the string (excluded). But inside the loop, you're doing
str.charAt(a+3)
Obviously, if a is length - 1, a + 3 is length + 2, and you're thus trying to access an element outside the bounds of the string.
Side note: you would understand your own code better if you indented it correctly.
Instead of
while (a <=b){
use
while (a <= b - 3){
Reason: Your end sign in the while is the condition that the start of the String "code" is inside the String. However, if a = b - 2, then a + 3 = b + 1 = (str.length() - 1 + 1) = str.length() which is just outside the String.
public int countCode(String str) {
int count = 0;
for(int i = 0; i < str.length()-3; i++)
if(str.substring(i, i+2).equals("co") && str.charAt(i+3) == 'e')
count++;
return count;
}
Related
I have to write a code for class using Java in which the number of occurrences of the letter E is counted and printed out (both cases included). This is what I have.
String sVerse = "As we enter our centennial year we are still young ";
System.out.println(sVerse);
int len3 = sVerse.length();
int countE = 0;
for (int d = 0; d <= len3; d++){
char e = sVerse.charAt(d);
d = d + 1;
if (e == 'e' || e == 'E')
{
countE = countE + 1;
}
else
{
countE = countE;
}
}
System.out.println(countE);
The code runs, and the string prints, but after the string prints I get this error:
java.lang.StringIndexOutOfBoundsException: String index out of range: 1258
at java.lang.String.charAt(Unknown Source)
at Unit4plus.main(Unit4plus.java:125)
You're increasing d inside the loop, which you shouldn't - just let the for loop do it's thing. Also, you should terminate the loop with <, not <=:
int countE = 0;
for (int d = 0; d < len3; d++) {
char e=sVerse.charAt(d);
if (e=='e' || e=='E') {
countE++;
}
}
But frankly, you could just stream the characters in the string for a much more elegant solution:
long countE = sVerse.chars().filter(c -> c == 'e' || c == 'E').count();
Your condition in the first loop should be :
d < len3
Since length starts at 1 but index of characters in your string are 0 based.
Moreover, your statement d=d+1 in the for loop is useless and makes you iterate 2 by 2 since you already increment it in the for loop with
d++
You need to change the condition for the loop since the length is +1 of the maximum index.You also increase the value of the variable "d" two times, one in the definition of the "for" loop, and the other is inside it. Try replace it with this code:
String sVerse = "As we enter our centennial year we are still young";
int len3 = sVerse.length();
int countE = 0;
for (int d = 0; d < len3; d++) {
char e = sVerse.charAt(d);
if (e == 'e' || e == 'E')
countE++;
}
System.out.println(countE);
Currently going through an exercise in my book, but i'm stuck ( I havent learned arrays yet, this chapter is on loops nested loops and for loops)
The first part of the problem is to take a credit card number and then sum every other number backwards
Consider 4358 9795, which should output the sum 5+7+8 + 3 = 23.
Heres my solution which isn't working
class Checkit{
private String creditNum;
private int sum;
public Checkit(String creditNum)
{
this.creditNum = creditNum;
sum = 0;
}
public int getSum()
{
for (int i = creditNum.length() ; i > 0 ; i--)
{
char ch = creditNum.charAt(i-1);
if(i%2 == 1 )
{
sum+=ch;
}
}
return sum;
}
}
public class test{
public static void main(String [] args)
{
Checkit sampleNumber = new Checkit("4358 9795");
System.out.println(sampleNumber.getSum());
}
}
I'm not exactly sure whats wrong with my logic. ch is taking all of the values of my credit card number 5,7,8,3. But for some reason the sum is messing up.
BONUS PART
Take Each number that wasn't added and double it, so 9+9 + 5 + 4, double each of those terms ( that becomes 18 + 18 + 10 + 8), and then get the sum of 1 + 8 + 1 + 8 + 1 + 0 + 8.
I tried the bonus part, but for some reason every time I get 9, 9, 5,4 and times that char value by 2, I get letters. I don't think I can multiply chars by integers, so should I do conversions? Note I didn't learn arrays yet
NEW CODE
class Checkit {
private String creditCardNum;
private int sum;
public Checkit(String creditCardNum) {
sum = 0;
this.creditCardNum = creditCardNum;
}
public int getSum() {
creditCardNum = creditCardNum.replaceAll("\\s+", "");
for (int i = creditCardNum.length(); i > 0; i--) {
char ch = creditCardNum.charAt(i - 1);
if (i % 2 == 0) {
sum += Character.getNumericValue(ch);
}
}
return sum;
}
public int doubleDigitSum() {
sum = 0;
creditCardNum = creditCardNum.replaceAll("\\s", "");
for (int i = creditCardNum.length(); i > 0; i--) {
char ch = creditCardNum.charAt(i - 1);
if (i % 2 == 1) {
int newChar = Character.getNumericValue(ch) * 2;
String newCharString = Integer.toString(newChar);
for (int j = 0; j < newCharString.length(); j++) {
char sumThis = newCharString.charAt(j);
sum += Character.getNumericValue(sumThis);
}
}
}
return sum;
}
}
public class DataSet{
public static void main(String [] args) {
Checkit data = new Checkit("4358 9795");
System.out.println(data.getSum());
System.out.println(data.doubleDigitSum());
}
}
You're adding char values rather than int values. Replace sum+=ch; with
sum += ch - '0';
The reason why this works as opposed to the original solution is that when you're adding char values to an int value, the char is converted to a decimal via its ASCII value. For example, '5' has a ASCII dec value of 53. However, '5' - '0' equals 5. More on these ASCII values can be found here, http://www.asciitable.com/
Your issue is that you are not converting the char to an integer:
public int getSum()
{
for (int i = creditNum.length() ; i > 0 ; i--)
{
char ch = creditNum.charAt(i-1);
if(i%2 == 1 )
{
sum+=ch;
}
}
return sum;
}
Fun fact that's causing your error - chars are numbers! They're simply a number that represents the ascii character code of the letter. So when you add them to a sum, Java is OK with that and just adds the corresponding number for the char '8' for example, which is 56.
To make your code work, you need to properly convert to an integer:
public int getSum()
{
for (int i = creditNum.length() ; i > 0 ; i--)
{
char ch = creditNum.charAt(i-1);
if(i%2 == 1)
{
sum+=Character.getNumericValue(ch);
}
}
return sum;
}
for (int i = creditNum.length() ; i > 0 ; i--) {
char ch = creditNum.charAt(i-1);
First iteration thru loop gets IndexOutOfBounds exception. And then you never check the initial character of the credit card number, since your termination criterion is ( i > 0 ), not (i >= 0)
And why not just use i -= 2 for the increment instead of the if-check?
i need help on a verification on a string
I have to write a method that verify if 2 parameters of the method have the same length and if the second one have numbers between 0 and 3.
Let's see what i wrote :
public static boolean coupEstValide( String combinaison, String coup ){
boolean res = true;
if(combinaison.length() == coup.length()){
int i = 0;
while(i < coup.length() && res == true){
char t = coup.charAt(i);
if(t <= 0 && t >= 3)
res = false;
i++;
}
}
return res;
in my opinion, this should work... But if i do this :
coupEstValide("555", "104");
it should tell me false but it it's telling me it's true.
Do you guys see what's wrong ?
Thanks
When you compare Character with an integer actually ASCII value of that character gets compared with that integer. That's why you keep getting true.
So as already suggested in the comments you should compare it either as if(t >= '0' && t <= '3') or use any Utility method of java.lang such as Character.compare(char lhs, char rhs).
Hope this would be helpful.
Enjoy!
A few of problems in your code:
If the lengths are different, you are still returning true!
Strings are composed of characters. Their value is their character code. 0 to 3 are 48 to 51, respectively. Use character constants not integer constants: if (t == '0') will check if t is the character "0".
Your logic for the comparison isn't right anyways. Using your original (incorrect) example with integers, and correcting from <= and >= based on your comments: if (t < 0 && t > 3) will never be true, t cannot simultaneously be less than 0 and greater than 3. I'll leave the correct boolean statement as an exercise to the reader (hint: or).
Alright, i fixed the problem.
So as you said, i should've use
if(t < '0' || t > '3')
And to fix the problem of the time both are not the same size, i added an else.
So the full code is that :
public static boolean coupEstValide( String combinaison, String coup ){
boolean res = true;
if(combinaison.length() == coup.length()){
int i = 0;
while(i < coup.length() && res == true){
char t = coup.charAt(i);
if(t < '0' || t > '3')
res = false;
i++;
}
}
else
res = false;
return res;
}
Thanks for your help guys !
This would never true. A number can not be less and equal to zero and at the same time greater and equal to 3.
if(t <= 0 && t >= 3)
If you want to evaluate whether a character is between 0 and 3 you must use this:
if(t >= '0' && t <= '3')
Now if you want to evaluate if the character is not between 0 and 3 then try this:
if (t <'0' || t> '3')
String coup = "053";
boolean res = true;
int i = 0;
while (i < coup.length() && res == true) {
System.out.println(coup.length());
int t = Integer.parseInt(coup.charAt(i) + "");
System.out.println("T is " + t);
if (t <= 0 || t >= 3) {
res = false;
i++;
}
System.out.println("Value i " + i);
System.out.println("Value of the Res at last" + res);
}
may be this could be helpful try to convert it to the integer
according to your code
String coup = "053";
boolean res = true;
int i = 1;
while (i < coup.length() && res == true) {
System.out.println(coup.length());
//int t = Integer.parseInt(coup.charAt(i) + "");
char t = coup.charAt(i);
System.out.println("T is " + t);
if (t <= 0 || t >= 3) {
res = false;
i++;
}
System.out.println("Value i " + i);
System.out.println("Value of the Res at last" + res);
}
I am trying to solve a problem . Hoping for some help here.
Objective: Find a number which is immediate next to input and contains only 4 and 7 in it.
Input : 1234
Output: 4444
Input : 4476
output: 4477
Input : 8327
Output : 44444
I am not looking for incrementing number and each time checking string characters for the pattern. That would be too slow for large numbers.
static String toOutput (int a) {
// I am trying here all the possible other ways
}
Check this answer. Hope this helps :)
private static String toOutput(int n) {
String input = String.valueOf(n+1);
// create input character array and output character array of one more in size
char[] inputChars = input.toCharArray();
char[] outputChars = new char[inputChars.length + 1];
boolean extra = false; //carry forward
// traverse input array from last position to first position
for (int i = inputChars.length - 1; i >= 0; i--) {
// for all other positions except last position check whether number is changed
// (i.e. apart from 4 or 7),
// change all higher digits in output array to 4
if ((i + 1) < inputChars.length) {
if (inputChars[i] != '4' && inputChars[i] != '7') {
for (int j = i + 1; j < inputChars.length; j++) {
outputChars[j + 1] = '4';
}
}
}
// if extra is true that means it is carry forward
if (extra == true) {
inputChars[i] = (char) ((int) inputChars[i] + 1);
}
// if input digit is less than equal to 4 output digit is 4 , extra is false
if (inputChars[i] <= '4') {
outputChars[i + 1] = '4';
extra = false;
}
// if input digit is between 4 to 7 output digit is 7 , extra is false
else if (inputChars[i] <= '7') {
outputChars[i + 1] = '7';
extra = false;
}
// if input digit is more than 7 output digit is 4 , extra is true
else {
outputChars[i + 1] = '4';
extra = true;
}
}
// if carry forward is true, make extra digit to 4 otherwise it is not required
if (extra == true) {
outputChars[0] = '4';
} else {
outputChars[0] = ' ';
}
return new String(outputChars).trim();
}
static String toOutput (long a) {
LinkedList<Long> q = new LinkedList<Long>();
q.add(4L);
q.add(7L);
while(!q.isEmpty()){
Long curr = q.pop();
if(curr>a)
return String.valueOf(curr);
q.add(curr*10+4);
q.add(curr*10+7);
}
return "";
}
This will solve the problem in close to O(LogN)
Since this is fundamentally a manipulation of character strings, a plausible solution is to use string functions, particularly regular expressions. Here's a compact solution:
class Incrementer {
Pattern p;
public Incrementer() {
p = Pattern.compile("(?:([47]*)([0-6]))?(.*)");
}
public String next(String s) {
Matcher m = p.matcher(s);
m.lookingAt();
return (m.group(1)==null
? '4'
: m.group(1) + (m.group(2).charAt(0) >= '4' ? '7' : '4'))
+ m.group(3).replaceAll(".", "4");
}
}
See it here.
(I'm not at all a Java programmer. Coding suggestions welcome.)
The regular expression matches the prefix of any sequence of legal digits (4 or 7) followed by an incrementable digit ( < 7). If that prefix is not matchable, the answer must be one digit longer, so it must start with the smallest legal digit (4). If the prefix is matchable, the prefix must be modified by bumping the last digit to the next legal digit. In both cases, all the digits following the (possibly empty) prefix are replaced with the smallest legal digit.
Of course, this could be done without actual regular expressions. The following essentially uses a state machine which implements the regular expression, so it might be faster. (Personally I find the regex version easier to verify, but YMMV):
public static String next(String s)
{
int toinc = -1;
for (int i = 0; i < s.length(); ++i) {
char c = s.charAt(i);
if (c < '7') {
toinc = i;
if (c != '4') break;
} else if (c > '7') break;
}
char[] outChars;
// Copy the prefix up to and including the character to be incremented
if (toinc < 0) {
outChars = new char[s.length() + 1];
} else {
outChars = new char[s.length()];
for (int i = 0; i < toinc; ++i)
outChars[i] = s.charAt(i);
// Increment the character to be incremented
outChars[toinc] = s.charAt(toinc) >= '4' ? '7' : '4';
}
// Fill with 4's.
for (int i = toinc + 1; i < outChars.length; ++i)
outChars[i] = '4';
return new String(outChars);
}
See it here.
*
public class PatternTest {
private static final char FOUR = '4';
private static final char SEVEN = '7';
public static void main(String[] args) {
Scanner scanner = new Scanner(new InputStreamReader(System.in));
String value = scanner.next();
char startChar = value.charAt(0);
Result result;
if (startChar == FOUR || startChar == SEVEN) {
result = getStartWith4Or7(value);
} else {
result = getNotStartWith4Or7(value);
}
System.out.println("Final value is : " + result.getValue());
}
private static Result getNotStartWith4Or7(String value) {
Result result = new Result();
char startChar = value.charAt(0);
if (startChar < FOUR) {
result.value = value.replaceAll(".", String.valueOf(FOUR));
} else if (startChar > SEVEN) {
result.value = value.replaceAll(".", String.valueOf(FOUR));
result.flag = FOUR;
} else if (startChar > FOUR && startChar < SEVEN) {
result.value = getSubString(value).replaceAll(".", String.valueOf(FOUR));
result.value = String.valueOf(SEVEN) + result.value;
}
return result;
}
private static Result getStartWith4Or7(String value) {
Result result = new Result();
if (value != null && !value.equalsIgnoreCase("")) {
char startChar = value.charAt(0);
if (startChar == FOUR || startChar == SEVEN) {
value = getSubString(value);
result = getStartWith4Or7(value);
result.value = getStartCharUpdate(startChar, result) + result.value;
} else {
result = getNotStartWith4Or7(value);
}
}
return result;
}
private static String getStartCharUpdate(char startChar, Result result) {
String newValue = String.valueOf(startChar);
if (result.flag == FOUR) {
if (startChar == FOUR) {
newValue = String.valueOf(SEVEN);
result.flag = 0;
} else {
newValue = String.valueOf(FOUR);
}
}
return newValue;
}
private static String getSubString(String value) {
int len = value.length();
String finalValue = "";
if (len > 1) {
finalValue = value.substring(1, len);
}
return finalValue;
}
static class Result {
String value = "";
char flag;
public String getValue() {
if (flag == FOUR) {
value = FOUR + value;
}
return value;
}
}
}
*
You can try something like this.
String num = "4476";
double immediateVal = 0;
int length = num.length();
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
for (int i = 0; i < length; i++) {
sb1.append("4");
sb2.append("7");
}
double valNum = Double.parseDouble(num);
double val1 = Double.parseDouble(sb1.toString());
double val2 = Double.parseDouble(sb2.toString());
if (valNum < val1) {
immediateVal = val1;
} else if (val1 <= valNum && valNum < val2) {
if(num.indexOf("4")==0){
int firstIndexOf7=-1;
for(int a=0;a<length;a++){
firstIndexOf7=num.indexOf("7");
if(firstIndexOf7!=-1){
break;
}
}
if(firstIndexOf7!=-1){
StringBuilder sb3=new StringBuilder();
for(int b=0;b<firstIndexOf7;b++){
sb3.append("4");
}
for(int b=firstIndexOf7;b<length;b++){
sb3.append("7");
}
immediateVal=Double.parseDouble(sb3.toString());
}
} else{
immediateVal = val2;
}
}else if(valNum>=val2){
immediateVal=Double.parseDouble(sb1.append("4").toString());
}
System.out.println(immediateVal);
this can help you
static String toOutput(String input){
char[] values = input.toCharArray();
StringBuilder result = new StringBuilder();
int length = values.length;
int currentPosition = 0;
for(char current: values){
Integer currentInt = new Integer(current);
if(currentInt<4){
//fill the string with 4, best result
for(currentPosition;currentPosition<length;currentPosition++){
result.append(4);
}
break;
}
else if(currentInt==4){
result.append(4);
currentPosition++;
continue;
}
else if(currentInt<=7){
result.append(7);
currentPosition++;
continue;
}
else if(currentInt>7){
if(currentPosition=0){
//fill the string with 4 but with length +1, best result
for(currentPosition;currentPosition<=length;currentPosition++){
result.append(4);
}
break;
}
else{
// you need work this case, change last 4 to 7 and fill the rest with 4. enjoy it.
}
}
return result.toString();
}
One approach would be reading the digits right to left and check if that is less than 4 or 7 and add 4 or 7 respectively.
One optimization would be check if first(from left) digit is >7 then its sure that you will have all 4's +1 extra 4`.
You need to take extra care at the left most digit. If the left most digit is greater than 7 you need to add two 4s.
EX: 1234
right to left `4` is `4`
`3` is `4`
`2` is `4`
`1` is `4`
This approach wont work if all the digits in the number are 4 or 7. You need to have one condition and change one or two chars accordingly.
private static String toOutput(int a) {
String s = Integer.toString(a);
StringBuilder sb = new StringBuilder();
if (Integer.valueOf(s.charAt(0)) > 7) {
for(int i=0; i<= s.length(); i++) {
sb.append("4");
}
return sb.toString();
}
for(int i=s.length()-1; i>=0; i--) {
Integer x = Integer.valueOf(i);
if(x <=4) {
sb.append(4);
} else {
sb.append(7);
}
}
return sb.reverse().toString();
}
This is not checking if the number has all 4's or 7's.
I don't think you need to worry about performance for converting a number into a String. You're evaluating a number as if it's a string, so it only makes sense to cast it to string to do the evaluation.
Something like this works and is reasonably fast.
public static int closestNumber(int num) {
for (int i = num + 1; i < Integer.MAX_VALUE; i++) {
if ((i+"").matches("^[47]+$")) {
return i;
}
}
throw new RuntimeException("Your number was too close to Integer's max value!");
}
Ok, I wrote it using mod and no strings:
public static int closestNumber(int num) {
for (int i = num + 1; i < Integer.MAX_VALUE; i++) {
if (containsOnly(i,4,7)) {
return i;
}
}
throw new RuntimeException("Your number was too close to Integer's max value!");
}
public static boolean containsOnly(int evaluate, int numeralA, int numeralB) {
while (evaluate > 0) {
int digit = evaluate % 10;
if (digit != numeralA && digit != numeralB) return false;
evaluate = evaluate / 10;
}
return true;
}
It looks like looking for the first digit that is not 4 or 7 counting from left to right.
Set up a index pointer to record the last index that hold digit "4" and check every digit from left to right.
Initial current pointer index (c) to -1 and set last "4" index (l) to -1
For every digit from left to right
update c (c+=1)
check digit value
digit = 7 -> do nothing
digit = 4 -> l = c
digit < 4 -> this digit change to "4", all remaining digits sets to "4", end check
4 < digit < 7 -> this digit change to "7", all remaining digits sets to "4", end check
digit > 7 -> do necessary change and end check
l = -1 => 444....444 (no. of digit = n+1)
l > -1 => digit at l change to "7", all digits after l change to "4"
Idea
For a n-digit value, if it contains only "4" or "7", you do nothing.
Then, if there is any non "4" or "7", what should it be?
Analyzing the pattern, we need to know the first occurrence of non "4"/"7" digit (from left to right) only and all digits after the digit will change to "4" to minimize the value since 444...444 is the least k-digit value for combination of "4" and "7" for all k.
Consider case Xcccccccc , c is any value
If X in {4,7}, consider case 2.
If X in {1,2,3}, the next value should be 444444444.
If X in {5,6}, the next value should be 744444444.
If X in {8,9}, the next value should be 4444444444
Consider case aaaaXcccc, if a are "4" or "7"
If X in {4,7}, consider case aaaaaXccc.
If X in {0,1,2,3}, the next value should be aaaa44444.
If X in {5,6}, the next value should be aaaa74444.
If X in {8,9}, the next value should be bbbb44444 or bbbbb44444.(b are "4" or "7")
then how to deduce bbbb or bbbbb?
if aaaa does not have any "4", you get bbbbb = 44444 (since aaaa=7777)
if aaaa have "4", you get bbbb ("4" will be replaced by "7", e.g. 474779 => 477444)
Consider case aaaaaaaaX, this should be same as case 2 except no remaining digit need to be handle
Combine case 1-3, when the first occurrence of non "4"/"7" digit is in {8,9}, the difference in change of value depends on whether there is any "4" before the digit.
The title is pretty much self explanatory. :)
1232 => 0
1231030 => 1
2000 => 3
34444400000 => 5
If it fits into an int/long, just check if the number modulo 10 is 0 and keep a counter:
long x = ...
if (x == 0) {
return 0;
}
int counter = 0;
while (x % 10 == 0) {
counter++;
x /= 10;
}
If it's too big to fit in long, store it in a String and count zeroes from the last char:
String s = ...
int counter = 0;
while(counter < s.length() && s.charAt(s.length() - 1 - counter) == '0') {
counter++;
}
Integer class has an inbuilt function to count the trailing zeros.
javadocs
int trailingZeroes = Integer.numberOfTrailingZeros(int i);
Three lines:
int zeroes = 0
while(num%10 == 0 && num != 0) {
zeroes++;
num /= 10;
}
This uses the modulus operator. As long as we can divide by ten without remainder, increment the counter.
Here is another solution using Java 8 Streams:
int trailingZeros = String.valueOf(number).chars()
.reduce(0, (count, ch) -> (ch == '0') ? count + 1 : 0);
This transforms the number to an IntStream. This stream is then reduced using a lambda which resets a counter each time a non-zero char comes up.
You could always just use a regular expression:
Pattern pattern = Pattern.compile("(0+)$");
Matcher matcher = pattern.matcher(String.valueOf(123140000));
Integer trailingZeroes = 0;
if (matcher.find()) {
trailingZeroes = matcher.group(1).length();
}
System.out.println(trailingZeroes);
you can turn the int to a String and iterate in reverse, counting the zeros until you find a char that is not zero:
int countZeros(int x){
String a = Integer.toString(x);
int numOfZeros = 0;
for(int i = a.length() - 1; i >= 0; i--)
if (a.charAt(i) != '0') break;
else numOfZeros ++;
return numOfZeros;
}
Testing with :
System.out.println(countZeros(25000)); will print 3
System.out.println(countZeros(25)); will print 0
Hope this helps.
Not tried this code but this should work.
int counterForZeros=0;
for(long i=10;true;)
{
if(num%i==0)
{
counterForZeros++;
i*=10;
}
else
{
break;
}
}
System.out.println("Number of zeros in "+num+" is "+counterForZeros);
Well, if this is a contest to see who can do it in the fewest lines:
trailingZeroes = String.valueOf(num).length() - String.valueOf(num).replaceAll("0*$","").length();