Does Java have a limit on loop cycles? - java

I solved the Project Euler problem #14 https://projecteuler.net/problem=14 on Java, but when I run it in Powershell, it stops iterating at exactly i = 113383 every time. I rewrote the solution on python, and it works perfectly fine, albeit slowly. According to my (identical) python solution, the answer is that the number that produces the longest chain is 837799 and the chain is 524 operations long.
Why does the Java solution not finish the for-loop? Is there some kind of limit in Java on how long it can stay in a loop? I cannot come up with any other explanation. Java code below. I wrote the System.out.println(i) there just to see what is going on.
class ProjectEuler14 {
public static void main(String[] args) {
int largestNumber = 1;
int largestChain = 1;
int currentNumber;
int chainLength;
for (int i = 2; i < 1000000; i++) {
System.out.println(i);
currentNumber = i;
chainLength = 0;
while (currentNumber != 1) {
if (currentNumber % 2 == 0) currentNumber /= 2;
else currentNumber = 3 * currentNumber + 1;
chainLength++;
}
if (chainLength > largestChain) {
largestChain = chainLength;
largestNumber = i;
}
}
System.out.println("\n\nThe number under million that produces the "
+ "longest chain is " + largestNumber +
" and the chain's length is " + largestChain);
}
}

It's not the for loop. It's the while loop. The condition currentNumber != 1 is always true; forever.
In java, an int is specifically defined as an integral number between -2^31 and +2^31 -1, inclusive, and operations 'roll over'. try it!
int x = 2^31 -1;
x++;
System.out.println(x);
this prints a large negative number (in fact, precisely -2^31).
It's happening in your algorithm, and that's why it never finishes.
A trivial solution is to 'upgrade' to longs; they are just as fast, really (yay 64-bit processors!) and use 64 bits, thus giving them a range of -2^63 to +2^63-1.
Python sort of scales up its numbers into slowness silently, java makes different choices (and, for crypto and other purposes, that rollover thing is in fact desired).
If you want to go even further, you can always use BigInteger, which grows as much as you need forever (becoming slower and taking more memory as it goes).
To know rollover occurred, the 3* operation would then result in a number that is lower than the original, and you can check for that:
replace:
else currentNumber = 3 * currentNumber + 1;
with:
else {
int newNumber = currentNumber * 3 + 1;
if (newNumber < currentNumber) throw new IllegalStateException("Overflow has occurred; 3 * " + currentNumber + " + 1 exceeds ints capacities.");
currentNumber = newNumber;
}
and rerun it. You'll see your app nicely explain itself.

The currentNumber is exceeding size of int, use long instead.

Do you hava problem overflow int.
Change int to long.
long largestNumber = 1;
long largestChain = 1;
long currentNumber;
long chainLength;
for (int i = 2; i < 1000000; i++) {
//System.out.println(i);
currentNumber = i;
chainLength = 0;
while (currentNumber != 1) {
//System.out.println("# = " + currentNumber);
if (currentNumber % 2 == 0) {
currentNumber /= 2;
} else {
currentNumber = (3 * currentNumber) +1 ;
}
chainLength++;
}
// System.out.println("################################ " + i);
if (chainLength > largestChain) {
largestChain = chainLength;
largestNumber = i;
}
}
System.out.println("\n\nThe number under million that produces the "
+ "longest chain is " + largestNumber
+ " and the chain's length is " + largestChain);

Related

How to change the sign ("+" "-") every other time in Java

I have to wright a function for Newtons approximation of Pi.
Newton calculated that Pi/(2* sqrt(2)) = 1+ 1/3 - 1/5 - 1/7 + 1/9 + 1/11 -...
public class newtonPi {
public static void main(String []args) {
int n = 10;
double piN = 0;
int sign = -1;
for(int i = 1; i < n; i+=2) {
System.out.println("i:"+i+" sign:"+sign);
piN += sign*(1.0/i);
sign *= -1;
}
System.out.println(piN*(2*Math.sqrt(2)));
}}
But with this approach, the sign changes everytime and not every other.
Thanks for the help :)
The pattern repeats every 8. Use the remainder operator % (aka modulo):
sign = n % 8 > 4 ? -1 : 1;
If I understood your question, you want to change the sign every two iterations, right? The problem is you're doing sign *= -1 on each iteration.
Try to use another variable in order to figure out if the sign must be inverted in the current iteration. Here is your code updated:
int sign = 1; // Start with positive
for(int i = 1,iteration = 0; i < n; i += 2,iteration++) {
System.out.println("i:" + i + " sign:" + sign);
piN += sign * (1.0 / i);
if(iteration % 2 != 0){
sign *= -1; // Change every 2 iterations, the odd ones
}
}

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.

Java: Dividing pairs from an Array

I am working on a project and am stuck on what to do next. I need to write a Java program that accepts from a user ten values and place those numbers in an array. The numbers in the array will be added together and the result displayed to the user. (I got that part)
Here is the problem: The program should compare the values for elements 1 and 2 (in the array) and divide the larger number by the smaller number. It should compare the values for all odd/even elements and divide the larger by the smaller value.
I do not know how to do this at all. I started with if-else statements but I am getting errors. It know it's a mess right now, but any help with dividing the array pairs would be very helpful. Send me links too, I have been unsuccessful finding any, so I can learn more.
Thanks!
Here is what I have so far:
/import java.util.Scanner;
public class ExceptionHandler {
/**
* #param args the command line arguments10
* 10
*/
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Please enter ten values:");
System.out.println();
// Input the data from the user.
int[ ] digit = new int[11];
int sum = 0;
//Declare an array
for (int i = 1; i < digit.length; i++) {
System.out.print("Value " + i + ": ");
digit[i] = in.nextInt();
sum += digit[i];
}
System.out.println("Total Values in Array:"+ sum);
// Calculate the sum and print the total
System.out.println("Would you like to divide values?");
// Fix this later
int result= digit[i];
if (digit[i] > digit[i + 1])
result = digit[i] / digit[i + 1];
else {
(digit[i + 1] / digit[i]);
}
// Compare element 0 with 1, divide larger element by smaller element
if (digit[i])> digit[i + 3])
result = digit[i] / digit[ i+ 3];
else{
(digit[i +3])/ digit[i];
}
}
You are using int for the division. Use a double instead, as it can divide two integers with decimal point precision.
// needed for division
double[] digit = new double[11];
for (int i = 0; i < digit.length; i++)
{
digit[i] = (double)in.nextInt;
sum += (int)digit[i];
}
//you can use this variable if needed, if not, ignore it
double[] divisionResult = new double[digit.length / 2];
for(int i = 1; i < digit.length; i += 2) {
double result = digit[i];
if (result > digit[i + 1])
result = result / digit[i + 1];
else {
result = digit[i + 1] / result;
}
divisionResult[i / 2] = result;
System.out.println(result);
}
EDIT: I'm also not sure why you're using
for(int i = 1; i < 11; i++)
Because you used that, I used it similarly above, but the actual convention should be:
for(int i = 0; i < 10; i++)
Doesn't make a huge difference, but better to follow good coding conventions :)
You can just use a for loop:
for (int i = 0; i < 10; i += 2) {
if (digit[i] > digit[i + 1]) {
result = digit[i] / digit[i + 1];
}
else {
result = digit[i + 1] / digit[i];
}
System.out.println(result);
}
This should work if I got it right what you want:
for (int i = 0; i < array.length; i = i+2) {
int firstDigit = array[i];
int secondDigit = array[i+1];
if (firstDigit > secondDigit) {
return firstDigit / secondDigit;
} else {
return secondDigit / firstDigit;
}
}
You iterate over the array and compare the first with the second element. By increasing your counterVariable (i) by two you always compare the 1st / 2nd, 3rd / 4th and so on numbers of the array.
Hope this helps :)
You variable i is local to the for loop in your code. If you want to use i again, you need to declare it outside of the loop to for you to use it outside the scope of the for loop. In addition, the last value of "i" here is the last array index, which would throw on array out of bound exception anyway (in other words you need to make another loop where you initialize "i" to 0 again under your "Would you like to divide values?" statement). Lastly, you need to do an assignment, so
(digit[i + 1] / digit[i]);
is not a valid statement. If you want to write it into result, you need to write:
result = (digit[i + 1] / digit[i]);
and if you want to override in place you can use
digit[i+1] = (digit[i + 1] / digit[i]);
or
digit[i + 1] /= digit[i];

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.

Categories