Reputation: 273
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
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
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
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
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
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:
java.util.Random
, specifically nextInt(int n)
to get a random int
in a given range
StringBuilder
.charAt
to index its letters.java.util.Random
int nextInt(int n)
StringBuilder
- A mutable sequence of characters.There are plenty, unfortunately.
String +=
in a loop yields very poor performance for longer stringsfor (int j = 0; j <= lengthOfName; j++)
is an off-by-one-errorfreq == 7 && freq == 8
is a logical contradictionI 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.
The simplest solution is to just have duplicates in the alphabet:
String alphabet = "aab";
will have probability for a
twice as much as b
alphabet
programmatically from a frequency table
Upvotes: 20
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
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
Reputation: 17750
Conditions like if(freq == X && freq == X+1)
are always false
.
You probably meant to use ||
(OR)
Upvotes: 5