bad result of my code - java

I seem to have a problem, where the output I expect is:
9000 + 200 + 50 + 6
But I get:
90000 + 2000 + 500 + 60
Here is my code:
class Kata
{
public static String expandedForm(int num) {
String s = String.valueOf(num);
StringBuilder result = new StringBuilder();
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) == '0') continue;
result.append(s.charAt(i) + makesZero(s.length() - i));
if(i != s.length() - 1) result.append(" + ");
}
return result.toString();
}
public static String makesZero(int num) {
StringBuilder result = new StringBuilder();
for(int i = 0; i < num; i++)
result.append("0");
return result.toString();
}
}
public class Main {
public static void main(String args[]) {
System.out.println(Kata.expandedForm(9256));
}
}

At
result.append(s.charAt(i) + makesZero(s.length() - i));
line you are appending character at position i and length - i zeroes. Lets see what happens for s="9256".
If i=0
s.charAt(i)->s.charAt(0)->'9' (that looks OK)
makesZero(s.length() - i) -> makesZero(4 - 0)) -> makesZero(4) -> "0000".
So as you see you are adding one extra zero because you didn't take into account that while 9 represents thousands, but thousands despite having 4 digits should have 3 zeroes. So you need to reduce one zero with
makesZero(s.length() - i - 1).
BTW builder.append(foo + bar) (when + represents concatenation, not addition) should be written as builder.append(foo).append(bar). Otherwise you are ending with something like
builder.append(new StringBuilder().append(foo).append(bar).toString())
which means you still need to create separate builder for each +.
We are using StringBuilder#append precisely so we could avoid + and such unnecessary object creation.

You're dealing with a classic off-by-one error. This is easily solved, but the larger problem with your approach is that you are solving the problem in an unnatural way, which makes your code more difficult to understand and debug. Determining how many zeroes to add is fundamentally a math problem but you are treating it like a string problem, which reduces the expressiveness of your code.
Here is a suggested rewrite of your expandedForm method that approaches this problem in a different way.
public static String expandedForm(int num) {
if (num == 0)
return "0";
int zeroes = (int) Math.log10(num);
StringBuilder result = new StringBuilder();
while (zeroes >= 0) {
int multiple = (int) Math.pow(10, zeroes);
int digit = num / multiple;
result.append(String.valueOf(digit * multiple));
if (zeroes > 0)
result.append(" + ");
num = num % multiple;
--zeroes;
}
return new String(result);
}

Just start your loop with i = 1 and i <= s. length()

Related

How can I loop through all the characters that are 0 in a given string?

I'm trying to remove trailing zeroes from an integer and here is my code so far.
import java.math.BigInteger;
public class newuhu {
public static int numTrailingZeros(int s) {
BigInteger J = BigInteger.valueOf(s);
String sb = J.toString();
String Y = "";
while (sb.length() > 0 && sb.charAt(sb.length() - 1) == '0') {
sb.replaceAll("0"," ");
}
return Integer.parseInt(Y);
}
Note: I turned my int into a Biginteger because I've been warned that some inputs may look like 20!, which is 2.432902e+18
However, my IntelliJ debugging tool tells me that variable sb isn't in the loop. So, I'm trying to understand what must be done to make sure sb is in the loop.
Please understand that I'm a beginner in Java so, I'm trying to learn something new.
replaceAll replaces all occurrences of string with character that you want (ie space) so you don't need loop at all, also you're concerned about overflow so you should actually use BigInteger as a parameter, not int (int wont fit anything close to 20!) but there's another issue with your code, you said you want to replace trailing zeros but right now you will replace every 0 with blank character, you should try to use something like https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html
public class newuhu {
public static int numTrailingZeros(BigInteger s) {
String sb = s.toString();
return Integer.parseInt(sb.replaceAll("0", "")); // consider returning something else if you're working with BigInteger
}
Keep in mind that when doing BigInteger.valueOf(int) does not have an effect as a number to big for int will never be stored in an int. Also 20! is fine for int.
public static String trimTrailingZeros(String source) {
for (int i = source.length() - 1; i > 0; ++i) {
char c = source.charAt(i);
if (c != '0') {
return source.substring(0, i + 1);
}
}
return ""; // or return "0";
}
Or if you prever BigInteger.
public static BigInteger trimTrailingZeros(BigInteger num) {
while (num.remainder(BigInteger.TEN).signum() == 0) {
num = num.divide(BigInteger.TEN);
}
return num;
}
This should be fast as you only create one string (via substring).
(First: variables and fields should start with a small letter - when no constants.)
It should be
sb = sb.replaceAll(...)
as sb is not changed by replaceAll, only the replaced value is returned. The class String gives immutable values, that always remain the same, so you can assign a variable to a variable and changing values of either variable will never influence the other - no further sharing.
Then it should be:
sb = sb.replaceFirst("0$", "");
replaceAll would replace every 0, like "23043500" to "23435".
replaceFirst replaces the _regular expression: char '0' at the end $.
Overflow on the input number is not possible, as you are already passing an int.
public static int numTrailingZeros(int n) {
while (n != 0 && n % 10 == 0) {
n /= 10;
}
return n;
}
public static int numTrailingZeros(String n) {
n = n.replaceAll("0+", "");
if (n.isEmpty() || n.equals("-")) { // "-0" for pessimists?
n = "0";
}
return Integer.parseInt(n);
}
% is the modulo operator, the remainder of an integer division 147 % 10 == 7.
The name is misleading, or you are calculating something different.
public static int numTrailingZeros(int n) {
int trailingZeros = 0;
while (n != 0 && n % 10 == 0) {
n /= 10;
++trailingZeros ;
}
return trailingZeros ;
}
The problem here is that sb.replaceAll("0","") won't do anything. You're throwing away the return value that contains your replaced string. See here.
What you probably want is something like this:
while (sb.length() > 0 && sb.charAt(sb.length() - 1) == '0') {
sb = sb.replaceAll("0"," ");
I'm not sure you need a while loop, though. ReplaceAll will... replace all of the zeros with spaces.

Fastest Way To Reverse Long Java [duplicate]

This question already has answers here:
Reverse a string in Java
(36 answers)
how to reverse an inputted number [duplicate]
(3 answers)
Closed 2 years ago.
What's the fastest way to reverse a Long value?
For example, 9876543210 should return 0123456789.
This is what I have right now:
long n = 0, c = 987654321 * 10; // *10 is to get 9876543210 as long value;
while (c > 0) n = n * 10 + c % 10;
System.out.println(n);
Your program encounters an infinite loop because you never change the value of c. Add c /= 10 at the end of each iteration and it will work, albeit the leading zero will be dropped due to it being a number.
long n = 0, c = 9876543210L;
while (c > 0){
n = n * 10 + c % 10;
c /= 10;
}
System.out.println(n);
If you need to have the leading zero, you should consider using Strings instead.
long c = 9876543210L;
final StringBuilder sb = new StringBuilder();
while (c > 0){
sb.append(c % 10);
c /= 10;
}
System.out.println(sb.toString());
I think this can be fast
long x = 1234567890L;
String reversed = new StringBuilder(Long.toString(x)).reverse().toString();
// reversed = "0987654321"
If You want to convert a reversed value to a long again:
long x = -1234567890000L;
StringBuilder reversed = new StringBuilder(Long.toString(x)).reverse();
System.out.println(reversed); // 0000987654321-
if (reversed.charAt(reversed.length() - 1) == '-') //remove `-` at last position
{
reversed.setLength(reversed.length() - 1);
}
while (reversed.charAt(0) == '0') //remove all `0` at the beginning
{
reversed.replace(0, 1, "");
}
System.out.println(reversed); // 987654321
long newLong = Long.parseLong(reversed.toString());
You can simply convert to string and then revert the String, in particular if you want string output in the end anyway. This should be quite straight forward and it has the leading 0, it might also be faster than doing calculations for each positions (but the cost of conversion in valueOf might cancel that advantage):
long c = 9876543210L;
String cAsString = String.valueOf(c);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < cAsString.length(); i++) {
builder.append(cAsString.substring(cAsString.length() - (i + 1), cAsString.length() - i));
}
System.out.println(builder.toString());
or as a one liner
long c = 9876543210L;
String reverted = new StringBuilder(String.valueOf(c)).reverse().toString();
System.out.println(reverted);
I did a little comparison between the options of the current answers:
public static void main(String[] args) {
Instant start = Instant.now();
for (long i = 0; i < 100_000_000; i++) {
stringbuilderWithDirectCalcs(i);
}
Duration duration = Duration.between(start, Instant.now());
System.out.println("Took " + duration);
}
protected static void stringbuilderWithDirectCalcs(long value) {
final StringBuilder sb = new StringBuilder();
while (value > 0) {
sb.append(value % 10);
value /= 10;
}
// System.out.println(sb.toString());
}
protected static void stringbuilderConvenient(long value) {
String reverted = new StringBuilder(String.valueOf(value)).reverse().toString();
//System.out.println(reverted);
}
protected static void stringbuilderHandCrafted(long value) {
String cAsString = String.valueOf(value);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < cAsString.length(); i++) {
builder.append(cAsString.substring(cAsString.length() - (i + 1), cAsString.length() - i));
}
//System.out.println(builder.toString());
}
I did three runs each. The outcome:
stringbuilderConvenient
Took PT6.988S / Took PT6.8S / Took PT6.68S
stringbuilderWithDirectCalcs:
Took PT6.17S / Took PT6.776S / Took PT6.692S
stringbuilderHandCrafted
Took PT18.205S / Took PT16.035S / Took PT17.025S
So, scanning the String by hand and sticking the StringBuilder together step by step seems out of the question. Obviously Stephen C was right in his comment that the calculations happen anyway when converting to String. But the approach based on Stringbuilder.reverse and handcalculating each position are pretty close (and any difference might be due to minor runtime fluctuations). So, one might choose the StringBuilder.reverse method over calculating each position by hand for readability with about the same performance.

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.

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.

how can i add values from a loop in java

I've recently been given question for uni that is in regards to a credit card statement which says i have a string of numbers, then i convert these numbers to separate integers then i increment them by the power of 10 depending on their position in the string using horners method
i then have to add the values i get from the loop to make 1 whole integer.
I Know this is an odd way to convert a string to an int but my assignment states that i have to use horners method to convert the string rather than use the inbuilt java classes/methods
My question is, How can i add the separate weighted numbers and concatenate them into one single number.
If it helps an example would be,
Given a card number 1234, the number is weighted according to its position and length so:
1 - 1000
2 - 200
3 - 30
4 - 4
Then these are added to create a whole number
1, 2, 3,4 ---> 1234
Here is my code thus far
public static long toInt(String digitString) {
long answer = 0;
long val = 0;
String s = "";
for (int j = 0; j < digitString.length(); j++) {
val = digitString.charAt(j) - '0';
val = (long) (val * Math.pow(10, (digitString.length() - 1) - j));
System.out.println(val);
}
return answer;
}
Most probably I am not following you, because this sounds too simple.
But to return a long (or integer) all you have to do is to sum these numbers:
public static long toLong(String digitString) {
long answer = 0;
long val = 0;
for (int j = 0; j < digitString.length(); j++) {
val = digitString.charAt(j) - '0';
val = (long) (val * Math.pow(10, (digitString.length() - 1) - j));
answer += val; // here! :)
//System.out.println(val);
}
return answer;
}
Please note that this is not going to work with negative numbers, so here is a more complex version:
public static long toLong(String digitString) {
long answer = 0;
long val = 0;
boolean negative = false;
int j = 0;
if (digitString.charAt(0) == '-') {
negative = true;
j = 1;
} else if (digitString.charAt(0) == '+')
j = 1;
for (; j < digitString.length(); j++) {
if (!Character.isDigit(digitString.charAt(j)))
throw new NumberFormatException(digitString);
val = digitString.charAt(j) - '0';
val = (long) (val * Math.pow(10, (digitString.length() - 1) - j));
answer += val;
}
return negative ? -answer : answer;
}
This code will work with negative numbers and with weird numbers that start with a + sign as well. If there is any other character, it will throw an exception.
I think your code is not Object-Oriented and really hard to read and understand.
Basic, the problem is a mapping and really simple.
If you are writing code in Java, better to use in OO way, though I don't like java very much.
Checkout my code
#Test
public void testCardScoreSystem() {
Map<String, String> scoreMapping = new HashMap<String, String>();
scoreMapping.put("1", "1000");
scoreMapping.put("2", "200");
scoreMapping.put("3", "30");
scoreMapping.put("4", "4");
String[] input = {"1", "2", "3", "4"};
long score = 0;
for (String str : input) {
String mappedValue = scoreMapping.get(str);
if (mappedValue == null) {
throw new RuntimeException("Hey dude, there is no such score mapping system! " + str);
}
score += Long.valueOf(mappedValue);
}
System.out.println(score);
}

Categories