Max
Max

Reputation: 273

Help for creating a random String

I need to create a random string which should be between the length of 6 to 10 but it sometimes generates only about the length of 3 to 5. Here's my code. Can anyone would be able to find out the problem? :(

            int lengthOfName = (int)(Math.random() * 4) + 6;
        String name = "";
        /* randomly choosing a name*/
        for (int j = 0; j <= lengthOfName; j++) {
            int freq = (int)(Math.random() * 100) + 1;
            if(freq <= 6){
                name += "a";
            }if(freq == 7 && freq == 8){
                name += "b";
            }if(freq >= 9 && freq <= 11){
                name += "c";
            }if(freq >= 12 && freq <= 15){
                name += "d";
            }if(freq >= 16 && freq <= 25){
                name += "e";                        
            }if(freq == 26 && freq == 27){
                name += "f";
            }if(freq == 28 && freq == 29){
                name += "g";
            }if(freq >= 30 && freq <= 33){
                name += "h";
            }if(freq >= 34 && freq <= 48){
                name += "i";
            }if(freq == 49 && freq == 50){
                name += "j";
            }if(freq >= 51 && freq <= 55){
                name += "k";
            }if(freq >= 56 && freq <= 60){
                name += "l";
            }if(freq == 61 && freq == 62){
                name += "m";
            }if(freq >= 63 && freq <= 70){
                name += "n";
            }if(freq >= 71 && freq <= 75){
                name += "o";
            }if(freq == 76 && freq == 77){
                name += "p";
            }if(freq == 78){
                name += "q";
            }if(freq >= 79 && freq <= 84){
                name += "r";
            }if(freq == 85 && freq == 86){
                name += "s";
            }if(freq == 87 && freq == 88){
                name += "t";
            }if(freq >= 89 && freq <= 93){
                name += "u";
            }if(freq == 94){
                name += "v";
            }if(freq == 95 && freq == 96){
                name += "w";
            }if(freq == 97){
                name += "x";
            }if(freq == 98 && freq == 99){
                name += "y";
            }if(freq == 100){
                name += "z";
            }
        }

Upvotes: 5

Views: 5524

Answers (8)

0x2bad
0x2bad

Reputation: 318

That's what I came up with

import java.util.*;
public class RandomString6to10

{
    public static void main(String[] args)
    {
        Random rnd = new Random();
        Scanner scan = new Scanner (System.in);
        String alphabets = "abcdefghijklmnopqrstuvwxyz";
        int min1 = rnd.nextInt(5) + 6;
        int min2 = rnd.nextInt(3) + 3;
        System.out.println("How many strings do you want?");
        int x = scan.nextInt();

        for ( int i = 0; i < x; i++)
        {
/* because you didn't tell us when should the generator decide to choose 6-10 or 3-5 
so I made it random */

            if (rnd.nextBoolean()) 
            { 
                min1 = rnd.nextInt(5) + 6;
                for (int t=0; t < min1; t++)
                {
                    int randomString1 = rnd.nextInt(alphabets.length());
                    System.out.print(alphabets.charAt(randomString1));
                }
                System.out.println();
            }
            else 
            {
                min2 = rnd.nextInt(3) + 3;
                for (int j=0; j < min2; j++)
                {
                    int randomString2 = rnd.nextInt(alphabets.length());
                    System.out.print(alphabets.charAt(randomString2));
                }
                System.out.println();

            }
        }
    }
}

Upvotes: 0

JnBrymn
JnBrymn

Reputation: 25353

I bet that you no longer need an answer, but since I've never answered a stack overflow question before, I though this would be a good warm-up problem.

One thing that everyone else seemed to leave out is the frequency aspect of your code. The following code will create 10 random words of length 6 to 10 according to the frequency you wanted:

import java.util.Random;


public class Stuff {
public static void main(String[] args) {

    Random rand = new Random();
    int[] freqs = new int[] {6,8,11,15,25,27,29,33,48,50,55,60,62,70,75,77,78,84,86,88,93,94,96,97,99,100};

    int numWords = 10;
    for(int i = 0; i<numWords; i++)
    {
        String word = "";
        int numLetters = 6 + rand.nextInt(5);
        for(int j = 0; j<numLetters; j++)
        {
            int freq = rand.nextInt(100) + 1;
            int index = 0;
            while(freqs[index] < freq) index++;
            word = word + (char)(97 + index );              
        }
        System.out.println(word);
    }
}

Now, my question for you is can you tell me how this works?

JB

Upvotes: 1

bakkal
bakkal

Reputation: 55448

Here is my solution:

import java.util.Random;

Random gen = new Random(474587); //put in random seed
int min = 6;
int max = 10;

// we want 20 random strings 
for(int i=0; i < 20; i++){
 int len = min+gen.nextInt(max-min+1);
 StringBuilder s = new StringBuilder(len);
 while(s.length() < len){
  //97 is ASCII for character 'a', and 26 is number of alphabets
  s.append((char)(97+gen.nextInt(26)));     
 }

System.out.println(s.toString());
}

Sample of output:

zqwloh
jefcso
spcnhxyyk
tzlobaukn
keyxkn
cllhsxybz
ieaudei
bolfzqlxrl
scpfcbztyh
thkfrybffe
nbspabxjh

Upvotes: 3

BalusC
BalusC

Reputation: 1108722

Just for reference and completeness, here's an "easy" (but less efficient) solution assuming that presence of numbers in the string isn't a big issue:

private static final Random random = new Random();

public static String generateRandomString() {
    return new BigInteger((4 + random.nextInt(3)) * 8, random).toString(36);
}

This generates a random string matching [a-z0-9] of length 6~10 (inclusive).

Upvotes: 0

polygenelubricants
polygenelubricants

Reputation: 383746

I'm sorry but the code is too poorly written to be salvageable. I recommend something like this.

    Random r = new Random(); // just create one and keep it around
    String alphabet = "abcdefghijklmnopqrstuvwxyz";

    final int N = 10;
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < N; i++) {
        sb.append(alphabet.charAt(r.nextInt(alphabet.length())));
    }
    String randomName = sb.toString();

    System.out.println(randomName);

Key points are:

  • Use java.util.Random, specifically nextInt(int n) to get a random int in a given range
    • No need for funky formulas
  • When building a string in a loop, use StringBuilder.
  • Use an alphabet string, and charAt to index its letters.

API links

Related questions


Problems with the original code

There are plenty, unfortunately.

  • String += in a loop yields very poor performance for longer strings
  • for (int j = 0; j <= lengthOfName; j++) is an off-by-one-error
  • freq == 7 && freq == 8 is a logical contradiction
  • It's just unnecessarily verbose!
    • Warning signs should go off whenever you write something like that

I highly recommend doing lots of small but simple exercises to learn Java basics. codingbat.com is great; it has hundreds of these, they're automatically graded so you'll know when your solution works as expected or not. It has sections on logic, strings, arrays, etc.


On uneven letter distribution

The simplest solution is to just have duplicates in the alphabet:

  • String alphabet = "aab"; will have probability for a twice as much as b
  • You can generate the alphabet programmatically from a frequency table
    • I'll leave this as an exercise (or you can ask another question if you need it)

Upvotes: 20

Jeff
Jeff

Reputation: 21

You seem to have made some typos. On one occasion you write

if(freq == 49 && freq == 50){ name += "j";

which is in fact never true.

Upvotes: 2

Paulo Guedes
Paulo Guedes

Reputation: 7259

Your code has a lot of repetitions of the same problem:

if(freq == 28 && freq == 29) { ... }

You are telling Java to follow a condition when freq equals to 28 AND freq equals to 29. It's impossible. You will want to use the OR operator:

if(freq == 28 || freq == 29) { ... }

What's happening now is that when freq equals to any number inside those mistaken conditions, nothing will be added to your string and it will become smaller.

Upvotes: 5

Soufiane Hassou
Soufiane Hassou

Reputation: 17750

Conditions like if(freq == X && freq == X+1) are always false.

You probably meant to use || (OR)

Upvotes: 5

Related Questions