java.lang.NumberFormatException using parseInt - java

I'm trying to take a digit from a string and perform operations on it. This is the relevant code I'm working on (updated):
String cardNumber;
String curNum;
long currentNum;
int firstNum;
int randNum;
int i;
long sum = 0;
while (i <= 15) {
//Delete this line if it doesnt work
currentNum = Long.parseLong(cardNumber.substring(i));
if (i % 2 == 0) {
//currentNum = Integer.parseInt(cardNumber.charAt(i));
currentNum = currentNum * 2;
if (currentNum > 9) {
currentNum = currentNum - 9;
sum = sum + currentNum;
}
else {
//currentNum = Integer.parseInt(cardNumber.charAt(i));
sum = sum + currentNum;
}
i++;
}
long lastVal = 10 - (sum % 10);
char charNum = (char) lastVal;
//add int to char statement here
cardNumber = cardNumber + charNum;
}
System.out.println(cardNumber);
userNum--;
}
The // code is another option I was working on and didn't want to lose, so if there's a way to make it work using that, that's great! The error message this code returns is:
Exception in thread "main" java.lang.NumberFormatException: For input string: "64406849400888"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Long.parseLong(Long.java:692)
at java.base/java.lang.Long.parseLong(Long.java:817)
at MasterCardGenerator.main(MasterCardGenerator.java:54)

You said you're trying to take "a" digit from a string. If that's truly the case, and you are trying to examine cardNumber one digit at a time, then you want cardNumber.substring(i, i+1) instead of cardNumber.substring(i).
Read the javadocs for substring(int) and substring(int, int) to understand why.

The problem is that the domain of integers is between [-2^31,2^31[, indeed between [-2,147,483,648 to +2,147,483,647]. A possible solution is to parse the string using Long.parseLong(arg)
public class Test{
public static void main(String []args){
System.out.println("Integer.MAX_VALUE: " + Integer.MAX_VALUE);
System.out.println("Long.MAX_VALUE: " + Long.MAX_VALUE);
Long var = Long.parseLong("267574698286122");
System.out.println("Printing content of 'var': " + var);
}
}
And the output is:
Integer.MAX_VALUE: 2147483647
Long.MAX_VALUE: 9223372036854775807
Printing content of 'var': 267574698286122

The problem is that the range string you are trying to format is larger than range of int.
To solve this problem, you need to change the line Integer.parseInt(cardNumber.substring(i)); with Long.parseLong(cardNumber.substring(i));.
See the range off different data types here. Also you can see, for int see here the Integer.MIN_VALUE and Integer.MAX_VALUE
and for long see here the Long.MIN_VALUE and Long.MAX_VALUE
UPDATED
As per updated question, String passed is 64406849400888 so valid index for i are 0 <= i <= 13. Apart from that above code looks fine. 64406849400888 can be parsed in long. See it the parsing here

Related

Formatting returned Strings?

I'm really new to coding and just got assigned my first coding homework involving methods and returns. I managed to struggle through and end up with this, which I'm pretty proud of, but I'm not quite sure it's right. Along with that, my return statements are all on the same lines instead of formatted how my teacher says they should be ("n is a perfect number", then the line below says "factors: x y z", repeated for each perfect number. Below are the exact instructions plus what it outputs. Anything will help!
Write a method (also known as functions in C++) named isPerfect that takes in one parameter named number, and return a String containing the factors for the number that totals up to the number if the number is a perfect number. If the number is not a perfect number, have the method return a null string (do this with a simple: return null; statement).
Utilize this isPerfect method in a program that prompts the user for a maximum integer, so the program can display all perfect numbers from 2 to the maximum integer
286 is perfect.Factors: 1 2 3 1 2 4 7 14
It should be
6 is perfect
Factors: 1 2 3
28 is perfect
Factors: 1 2 4 7 14
public class NewClass {
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
System.out.print("Enter max number: ") ;
int max = input.nextInt() ;
String result = isPerfect(max) ;
System.out.print(result) ;
}
public static String isPerfect(int number) {
String factors = "Factors: " ;
String perfect = " is perfect." ;
for (int test = 1; number >= test; test++) {
int sum = 0 ;
for (int counter = 1; counter <= test/2; counter++) {
if (test % counter == 0) {
sum += counter ;
}
}
if (sum == test) {
perfect = test + perfect ;
for (int counter = 1; counter <= test/2; counter++) {
if (test % counter == 0) {
factors += counter + " " ;
}
}
}
}
return perfect + factors ;
}
}
Couple of things you could do:
Firstly, you do not need two loops to do this. You can run one loop till number and keep checking if it's divisible by the iterating variable. If it is, then add it to a variable called sum.
Example:
.
factors = []; //this can be a new array or string, choice is yours
sum=0;
for(int i=1; i<number; i++){
if(number % i == 0){
sum += i;
add the value i to factors variable.
}
}
after this loop completes, check if sum == number, the if block to return the output with factors, and else block to return the output without factors or factors = null(like in the problem statement)
In your return answer add a newline character between perfect and the factors to make it look like the teacher's output.
You can try the solution below:
public String isPerfect(int number) {
StringBuilder factors = new StringBuilder("Factors: ");
StringBuilder perfect = new StringBuilder(" is perfect.");
int sum = 0;
for (int i = 1; i < number; i++) {
if (number % i == 0) {
sum += i;
factors.append(" " + i);
}
}
if (sum == number) {
return number + "" + perfect.append(" \n" + factors);
}
return number + " is not perfect";
}
Keep separate variables for your template bits for the output and the actual output that you are constructing. So I suggest that you don’t alter factors and perfect and instead declare one more variable:
String result = "";
Now when you’ve found a perfect number, add to the result like this:
result += test + perfect + '\n' + factors;
for (int counter = 1; counter <= test/2; counter++) {
if (test % counter == 0) {
result += counter + " ";
}
}
result += '\n';
I have also inserted some line breaks, '\n'. Then of course return the result from your method:
return result;
With these changes your method returns:
6 is perfect.
Factors: 1 2 3
28 is perfect.
Factors: 1 2 4 7 14
Other tips
While your program gives the correct output, your method doesn’t follow the specs in the assignment. It was supposed to check only one number for perfectness. Only your main program should iterate over numbers to find all perfect numbers up to the max.
You’ve got your condition turned in an unusual way here, which makes it hard for me to read:
for (int test = 1; number >= test; test++) {
Prefer
for (int test = 1; test <= number; test++) {
For building strings piecewise learn to use a StringBuffer or StringBuilder.
Link
Java StringBuilder class on Javapoint Tutorials, with examples.

Why is this code giving me a strange output

The method below was written to make a String version of a number, I know there are already methods that do this, such as String.valueOf(), Double.toString(), or even just "" + someNumber.
private static String numToString(double i) {
String revNumber = "";
boolean isNeg = false;
if (i == 0) { //catch zero case
return "0";
}
if (i < 0) {
isNeg = true;
}
i = Math.abs(i);
while (i > 0) { //loop backwards through number, this loop
//finish, otherwise, i would not get any output in 'main()'
revNumber += "" + i % 10; //get the end
i /= 10; //slice end
}
String number = ""; //reversed
for (int k = revNumber.length() - 1; k >= 0; k--) {
number += revNumber.substring(k, k + 1);
}
revNumber = null; //let gc do its work
return isNeg ? "-" + number : number; //result expression to add "-"
//if needed.
}
Although the above method should only be used for ints (32-bit), I made it accept a double (64-bit) argument and I passed a double argument, without a decimal, the output results are the same if I pass an int into the method as well, or with a decimals, etc...
Test:
public static void main(String[] args) {
double test = -134; //Passing double arg
System.out.println(numToString(test)); //results
}
Result: (Maximum memory results for double?):
-323-E5.1223-E33.1123-E43.1023-E43.1913-E43.1813-E43.1713-E43.1613-E43.1513-E43.1413-E43.1313-E43.1213-E43.1113-E43.1013-E43.1903-E43.1803-E999999999999933.1703-E999999999999933.1603-E999999999999933.1503-E999999999999933.1403-E9899999999999933.1303-E999999999999933.1203-E999999999999933.1103-E8899999999999933.1003-E9899999999999933.1992-E999999999999933.1892-E999999999999933.1792-E999999999999933.1692-E999999999999933.1592-E999999999999933.1492-E999999999999933.1392-E999999999999933.1292-E999999999999933.1192-E999999999999933.1092-E999999999999933.1982-E999999999999933.1882-E1999999999999933.1782-E999999999999933.1682-E999999999999933.1582-E999999999999933.1482-E999999999999933.1382-E999999999999933.1282-E1999999999999933.1182-E1999999999999933.1082-E2999999999999933.1972-E2999999999999933.1872-E3999999999999933.1772-E2999999999999933.1672-E1999999999999933.1572-E2999999999999933.1472-E999999999999933.1372-E999999999999933.1272-E1999999999999933.1172-E2999999999999933.1072-E2999999999999933.1962-E1999999999999933.1862-E999999999999933.1762-E999999999999933.1662-E999999999999933.1562-E999999999999933.1462-E999999999999933.1362-E999999999999933.1262-E999999999999933.1162-E999999999999933.1062-E999999999999933.1952-E999999999999933.1852-E999999999999933.1752-E999999999999933.1652-E999999999999933.1552-E999999999999933.1452-E999999999999933.1352-E999999999999933.1252-E999999999999933.1152-E999999999999933.1052-E9899999999999933.1942-E9899999999999933.1842-E999999999999933.1742-E999999999999933.1642-E999999999999933.1542-E999999999999933.1442-E999999999999933.1342-E999999999999933.1242-E999999999999933.1142-E9899999999999933.1042-E999999999999933.1932-E8899999999999933.1832-E9899999999999933.1732-E8899999999999933.1632-E8899999999999933.1532-E8899999999999933.1432-E999999999999933.1332-E9899999999999933.1232-E8899999999999933.1132-E7899999999999933.1032-E8899999999999933.1922-E8899999999999933.1822-E7899999999999933.1722-E6899999999999933.1622-E5899999999999933.1522-E5899999999999933.1422-E6899999999999933.1322-E6899999999999933.1222-E6899999999999933.1122-E7899999999999933.1022-E7899999999999933.1912-E7899999999999933.1812-E8899999999999933.1712-E8899999999999933.1612-E7899999999999933.1512-E7899999999999933.1412-E6899999999999933.1312-E6899999999999933.1212-E7899999999999933.1112-E7899999999999933.1012-E7899999999999933.1902-E7899999999999933.1802-E6899999999999933.1702-E7899999999999933.1602-E7899999999999933.1502-E8899999999999933.1402-E8899999999999933.1302-E8899999999999933.1202-E8899999999999933.1102-E7899999999999933.1002-E7899999999999933.1991-E9899999999999933.1891-E9899999999999933.1791-E8899999999999933.1691-E7899999999999933.1591-E8899999999999933.1491-E8899999999999933.1391-E999999999999933.1291-E9899999999999933.1191-E9899999999999933.1091-E999999999999933.1981-E999999999999933.1881-E999999999999933.1781-E999999999999933.1681-E999999999999933.1581-E1999999999999933.1481-E999999999999933.1381-E999999999999933.1281-E1999999999999933.1181-E2999999999999933.1081-E999999999999933.1971-E1999999999999933.1871-E999999999999933.1771-E2999999999999933.1671-E3999999999999933.1571-E3999999999999933.1471-E2999999999999933.1371-E2999999999999933.1271-E2999999999999933.1171-E999999999999933.1071-E999999999999933.1961-E999999999999933.1861-E999999999999933.1761-E999999999999933.1661-E999999999999933.1561-E999999999999933.1461-E8899999999999933.1361-E8899999999999933.1261-E8899999999999933.1161-E7899999999999933.1061-E7899999999999933.1951-E7899999999999933.1851-E7899999999999933.1751-E7899999999999933.1651-E7899999999999933.1551-E6899999999999933.1451-E6899999999999933.1351-E6899999999999933.1251-E6899999999999933.1151-E6899999999999933.1051-E7899999999999933.1941-E6899999999999933.1841-E7899999999999933.1741-E7899999999999933.1641-E9899999999999933.1541-E999999999999933.1441-E999999999999933.1341-E999999999999933.1241-E999999999999933.1141-E999999999999933.1041-E999999999999933.1931-E9899999999999933.1831-E999999999999933.1731-E999999999999933.1631-E8899999999999933.1531-E9899999999999933.1431-E9899999999999933.1331-E8899999999999933.1231-E8899999999999933.1131-E8899999999999933.1031-E7899999999999933.1921-E7899999999999933.1821-E7899999999999933.1721-E6899999999999933.1621-E7899999999999933.1521-E7899999999999933.1421-E8899999999999933.1321-E7899999999999933.1221-E7899999999999933.1121-E8899999999999933.1021-E8899999999999933.1911-E9899999999999933.1811-E999999999999933.1711-E999999999999933.1611-E999999999999933.1511-E999999999999933.1411-E1999999999999933.1311-E2999999999999933.1211-E3999999999999933.1111-E2999999999999933.1011-E2999999999999933.1901-E3999999999999933.1801-E2999999999999933.1701-E2999999999999933.1601-E3999999999999933.1501-E2999999999999933.1401-E3999999999999933.1301-E3999999999999933.1201-E4999999999999933.1101-E5999999999999933.1001-E4999999999999933.199-E3999999999999933.189-E3999999999999933.179-E3999999999999933.169-E4999999999999933.159-E4999999999999933.149-E4999999999999933.139-E4999999999999933.129-E4999999999999933.119-E4999999999999933.109-E4999999999999933.198-E4999999999999933.188-E4999999999999933.178-E3999999999999933.168-E3999999999999933.158-E3999999999999933.148-E3999999999999933.138-E3999999999999933.128-E4999999999999933.118-E3999999999999933.108-E3999999999999933.197-E3999999999999933.187-E3999999999999933.177-E4999999999999933.167-E3999999999999933.157-E3999999999999933.147-E3999999999999933.137-E3999999999999933.127-E3999999999999933.117-E4999999999999933.107-E5999999999999933.196-E5999999999999933.186-E5999999999999933.176-E4999999999999933.166-E4999999999999933.156-E4999999999999933.146-E4999999999999933.136-E3999999999999933.126-E3999999999999933.116-E3999999999999933.106-E3999999999999933.195-E2999999999999933.185-E1999999999999933.175-E2999999999999933.165-E2999999999999933.155-E2999999999999933.145-E2999999999999933.135-E3999999999999933.125-E4999999999999933.115-E4999999999999933.105-E2999999999999933.194-E1999999999999933.184-E2999999999999933.174-E2999999999999933.164-E2999999999999933.154-E1999999999999933.144-E1999999999999933.134-E2999999999999933.124-E2999999999999933.114-E2999999999999933.104-E3999999999999933.193-E3999999999999933.183-E3999999999999933.173-E2999999999999933.163-E2999999999999933.153-E999999999999933.143-E2999999999999933.133-E2999999999999933.123-E2999999999999933.113-E3999999999999933.103-E3999999999999933.192-E3999999999999933.182-E3999999999999933.172-E3999999999999933.162-E4999999999999933.152-E4999999999999933.142-E5999999999999933.132-E6999999999999933.122-E7999999999999933.112-E6999999999999933.102-E6999999999999933.191-E7999999999999933.181-E8999999999999933.171-E8999999999999933.161-E8999999999999933.151-E9999999999999933.141-E8999999999999933.131-E8999999999999933.121-E43.111-E43.101-E43.19-E1000000000000043.18-E1000000000000043.17-E43.16-E43.15-E43.14-E43.143100.04310.0431.043.14000000000000004.30.4
This is not because of the complier. It is happening because you are doing
i /= 10; //slice end
So when you do 13.4 after the first run it wont give you 1.34 it will give you something like 1.339999999999999999 which is 1.34.
Check Retain precision with double in Java for more details.
If you just want to reverse the number you can do
private static String numToString(double i) {
String returnString = new StringBuilder(Double.toString(i)).reverse().toString();
return i>=0?returnString:"-"+returnString.substring(0,returnString.length()-1);
}
for (; i > 0; ) { //loop backwards through number
revNumber += "" + i % 10; //get the end
i /= 10; //slice end
}
This loop never finishes until it breaks at a much later time than it should. i % 10 doesn't cut off the end of a double. It works well with an int but not with a double. Hence the 134->13.4->1.34->.134-> etc.... So you get an argumentoutofrange exception or something similar to that. Else the compiler just keeps doing it for the max memory that a double can handle.

Project Euler N# 8 JAVA

I am trying to solve this problem and I think I am in the right track but for some reason the program does not run in a specific condition.
This is the code:
public class Eight {
public static void main(String[] args) {
String set = "731671765313306249192251196744265747423"
+ "553491949349698352031277450632623957831801698"
+ "480186947885184385861560789112949495459501737958"
+ "331952853208805511125406987471585238630507156932909"
+ "632952274430435576689664895044524452316173185640309871"
+ "112172238311362229893423380308135336276614282806444486645"
+ "238749303589072962904915604407723907138105158593079608"
+ "66701724271218839987979087922749219016997208880937"
+ "7665727333001053367881220235421809751254540594752"
+ "243525849077116705560136048395864467063244157221"
+ "55397536978179778461740649551492908625693219784"
+ "686224828397224137565705605749026140797296865"
+ "241453510047482166370484403199890008895243450"
+ "6585412275886668811642717147992444292823086346567481391912316282458617866458"
+ "3591245665294765456828489128831426076900422421902267105562632111110937054421750694165"
+ "8960408071984038509624554443629812309878799272442849091888458015616609791913387549920052"
+ "4063689912560717606058861164671094050775410022569831552000559357297257163626956188267042"
+ "8252483600823257530420752963450";
int initialIndex = 0;
int lastIndex = 4;
int finale = 0;
for (;last <= set.length() - 1; initialIndex++, lastIndex++)
{
int num = Integer.parseInt(set.substring(initialIndex, lastIndex));
int result = 1;
while (num > 0)
{
int digit = num % 10;
result *= digit;
num /= 10;
}
if (result > finale)
finale = result;
} //end for
System.out.println(finale);
}
}
When lastIndex equals 4, the result I get is 5832, which is the same result as Project Euler gives you as an example. But when Im trying to run this program with 13 numbers instead of 4, I get an exception and the program does not run.
A 13 digit string will exceed the maximum allowable size of an int. Use Long.parseLong and change num from int to long. I did it, and got the following when I used 13 digits: 2091059712
Your issue begins here:
int num = Integer.parseInt(set.substring(initialIndex, lastIndex));
When you set lastIndex as 13, the number you are trying to take out of the string is 7,316,717,653,133. In your code, you are trying to parse that String as an int, which has a maximum value of 2^31 2,147,483,647.
You can fix your problem by making any variable you expect to excede 2^31 a different integral data type, like a long.

How to create a list of strings that contain randomly generated numbers in Java?

I need to be able to create a function that generates a selected number of strings with randomly generated positive numbers added into them that are based on a string mask.
Example of a string mask where [n#] represents a positive number with a certain number of digits:
generateStrings(2, "( (-[n2]) + [n5] ) / [n1]");
The first number tells the function how many strings to generate.
2 generated strings:
( (-23) + 47269 ) / 9
( (-12) + 17935 ) / 1
I'd like to be able to generate strings with numbers ranging from 1 digit to 10 digits.
EDIT:Here is a function that can generate a number with digits ranging from 1 to 10:
public static int generateNumber(int n) {
int m;
if (n==1){
m = (0 + (int)(Math.random() * ((9 - 0) + 1)));
} else if (n==2) {
m = (10 + (int)(Math.random() * ((99 - 10) + 1)));
} else if (n==3) {
m = (100 + (int)(Math.random() * ((999 - 100) + 1)));
} else if (n==4) {
m = (1000 + (int)(Math.random() * ((9999 - 1000) + 1)));
} else if (n==5) {
m = (10000 + (int)(Math.random() * ((99999 - 10000) + 1)));
} else if (n==6) {
m = (100000 + (int)(Math.random() * ((999999 - 100000) + 1)));
} else if (n==7) {
m = (1000000 + (int)(Math.random() * ((9999999 - 1000000) + 1)));
} else if (n==8) {
m = (10000000 + (int)(Math.random() * ((99999999 - 10000000) + 1)));
} else if (n==9) {
m = (100000000 + (int)(Math.random() * ((999999999 - 100000000) + 1)));
} else if (n==10) {
m = (1000000000 + (int)(Math.random() * ((2147483647 - 1000000000) + 1)));
}
return m;
}
Now I just need to be able to apply that function to a string mask.
EDIT3: Here is a script that should generate a single string with a string mask in the format above:
public static String generateString(String mask) {
for (int i = 1; i < 10; i++)
{
String searchString = "[n" + i + "]";
int lastIndex = 0;
int count = 0;
while(lastIndex != -1){
lastIndex = mask.indexOf(searchString,lastIndex);
if( lastIndex != -1){
count ++;
lastIndex+=searchString.length();
}
}
for (int j=count; j > 0;) {
while(lastIndex != -1){
lastIndex = mask.indexOf(searchString,lastIndex);
if( lastIndex != -1){
count ++;
lastIndex+=searchString.length();
}
}
mask = mask.replaceFirst(searchString, String.valueOf(generateNumber(i)));
}
}
return mask;
}
I don't know if this script would work, and I don't know how to test my code, so I would appreciate it if someone would verify if it works.
Part of this code was from ansible's answer, and another part is from codebreach's answer to this question: Occurrences of substring in a string I just want to give them credit for the work that they did.
If you want to learn Java from the scratch you start with generating a random int, converting this int to a String. The String can be used to build your desired output.
But if you are lazy and only want to write a single line of code you can use RandomStringUtils from the apache commons library. However this assumes you know how to add a external lib to your class path.
String out = RandomStringUtils.randomNumeric(n);
One suggestion see how your if/else block is repetitive? We can use the power function to make concise.
public static int generateNumber(int n) {
int lowerBound = (int) Math.pow(10,num-1);
int upperBound = (int) Math.pow(10,num) - 1;
int random = lowerBound + (int)(Math.random() * ((upperBound - lowerBound) + 1 ));
return random;
}
Now, you probably want to search the string letter my letter looking for a [.
Then as you read line by line, create a new string but once you reach a [ you will need to do something else, until you find the corresponding ] bracket. What do you do when you find one of those?
Once you can do that, then you can do it multiple times depending on what was passed in.
If you have specific questions then post what you have an what problem you are running into.
Update:
Yes, see this is a better question already. Instead of just asking someone to do the problem you come up with a solution and ask a question when you get stuck.
The solution to this problem is similar to the problem with your random number function. You are explicitly listing out all of the possibilities instead of using variables and loops to do it for you.
What about this
for (int i = 1; i < 10; i++)
{
String searchString = "[n" + i + "]";
mask = mask.replaceFirst(searchString, String.valueOf(generateNumber(i)));
}
Now this will replace only the first instance of each string, we want to keep LOOPING over the mask to find all of the instance of each string. How would you that?
Edit 2:
Okay a few things. replaceAll takes in a regex, so the brackets were messing things up (at least for me). I solved this by first searching for "n1", "n2",.. then removed all the brackets.
Second, the while loop you have in the second for loop isn't doing anything. I'm guessing a copy/paste error?
Third, we can move the .replaceFirst into the while loop. Putting it all together looks like this.
public static String generateString(String mask) {
for (int i = 1; i < 10; i++)
{
String searchString = "n" + i;
int lastIndex = 0;
while(lastIndex != -1){
lastIndex = mask.indexOf(searchString,lastIndex);
if( lastIndex != -1){
mask = mask.replaceFirst(searchString, String.valueOf(generateNumber(i)));
}
}
}
mask = mask.replaceAll("\\[", "").replaceAll("\\]","");
return mask;
}
So basically what you had, but a few modifications for readability and fixed the regex issues.
This does work for me. The only thing you have to do now is wrap it in a loop so output the number of strings you would like.
One thing to note, is what we are doing is very inefficient. Each time we run .replaceAll or replaceFirst we could be looping through the entire string. We do this at least 11 times. This could be done with a single pass through the string instead, looking for [nX], and replacing them with our random numbers. I suggest you give it a try.

Iterate through each digit in a number

I am trying to create a program that will tell if a number given to it is a "Happy Number" or not. Finding a happy number requires each digit in the number to be squared, and the result of each digit's square to be added together.
In Python, you could use something like this:
SQUARE[d] for d in str(n)
But I can't find how to iterate through each digit in a number in Java. As you can tell, I am new to it, and can't find an answer in the Java docs.
You can use a modulo 10 operation to get the rightmost number and then divide the number by 10 to get the next number.
long addSquaresOfDigits(int number) {
long result = 0;
int tmp = 0;
while(number > 0) {
tmp = number % 10;
result += tmp * tmp;
number /= 10;
}
return result;
}
You could also put it in a string and turn that into a char array and iterate through it doing something like Math.pow(charArray[i] - '0', 2.0);
Assuming the number is an integer to begin with:
int num = 56;
String strNum = "" + num;
int strLength = strNum.length();
int sum = 0;
for (int i = 0; i < strLength; ++i) {
int digit = Integer.parseInt(strNum.charAt(i));
sum += (digit * digit);
}
I wondered which method would be quickest to split up a positive number into its digits in Java, String vs modulo
public static ArrayList<Integer> splitViaString(long number) {
ArrayList<Integer> result = new ArrayList<>();
String s = Long.toString(number);
for (int i = 0; i < s.length(); i++) {
result.add(s.charAt(i) - '0');
}
return result; // MSD at start of list
}
vs
public static ArrayList<Integer> splitViaModulo(long number) {
ArrayList<Integer> result = new ArrayList<>();
while (number > 0) {
int digit = (int) (number % 10);
result.add(digit);
number /= 10;
}
return result; // LSD at start of list
}
Testing each method by passing Long.MAX_VALUE 10,000,000 times, the string version took 2.090 seconds and the modulo version 2.334 seconds. (Oracle Java 8 on 64bit Ubuntu running in Eclipse Neon)
So not a lot in it really, but I was a bit surprised that String was faster
In the above example we can use:
int digit = Character.getNumericValue(strNum.charAt(i));
instead of
int digit = Integer.parseInt(strNum.charAt(i));
You can turn the integer into a string and iterate through each char in the string. As you do that turn that char into an integer
This code returns the first number (after 1) that fits your description.
public static void main(String[] args) {
int i=2;
// starting the search at 2, since 1 is also a happy number
while(true) {
int sum=0;
for(char ch:(i+"").toCharArray()) { // casting to string and looping through the characters.
int j=Character.getNumericValue(ch);
// getting the numeric value of the current char.
sum+=Math.pow(j, j);
// adding the current digit raised to the power of itself to the sum.
}
if(sum==i) {
// if the sum is equal to the initial number
// we have found a number that fits and exit.
System.out.println("found: "+i);
break;
}
// otherwise we keep on searching
i++;
}
}

Categories