0

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.

Community
  • 1
  • 1
  • Have you tried breaking down the problem? Are you stuck on an abstraction? – Janis F Feb 05 '14 at 20:32
  • Let's break the problem up. How would you go about creating a random number with a certain number of digits? What have you tried? What issues are you running into? – ansible Feb 05 '14 at 20:33
  • @ansible I guess for a 5-digit number you could do something like this: `10000 + (int)(Math.random() * ((99999 - 10000) + 1))` I got that from this question: [Generating random numbers in a range with Java](http://stackoverflow.com/questions/363681/generating-random-numbers-in-a-range-with-java) – INeedTogepi Feb 05 '14 at 20:37
  • Good - now how would you create that into a function that could take a number of digits and return a random number with the correct digits? Post your code in your question. Then try and think of what the next step would be, post that in the question. – ansible Feb 05 '14 at 20:41
  • See http://stackoverflow.com/questions/41107/how-to-generate-a-random-alpha-numeric-string – Raedwald Feb 05 '14 at 21:17

2 Answers2

1

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);
Spindizzy
  • 7,244
  • 1
  • 19
  • 33
0

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.

ansible
  • 3,569
  • 2
  • 18
  • 29
  • I edited my answer to include what I think would work, but I'm not entirely sure. – INeedTogepi Feb 05 '14 at 22:13
  • Why do you have `"\\["` and `"\\]"` instead of `"["` and `"]"`? – INeedTogepi Feb 05 '14 at 23:48
  • @MasterofTheKingdom - Because brackets are special charters in regular expressions, so we need to escape them first using a `\` so we want `\[`, but in Java you need to escape the backslash too, so you we need to do `\\[` and `\\]` for the regex to work correctly. I'm not really an expert with regular expressions, so there is probably a better way to do this, but this did work for me. – ansible Feb 06 '14 at 00:08