Я должен создать случайную строку, которая должна быть между длиной 6 - 10, но она иногда генерирует только о длине 3 - 5. Вот мой код. Может кто-либо мочь узнать проблему?:(
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";
}
}
Простите, но код написан слишком плохо, чтобы его можно было восстановить. Я рекомендую что-то подобное.
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);
Ключевые моменты:
java.util.Random
, в частности nextInt (int n)
, чтобы получить случайное int
в заданном диапазоне.
StringBuilder
. charAt
для индексации ее букв. java.util.Random
int nextInt (int n)
StringBuilder
- изменяемая последовательность символов. К сожалению, их много.
String + =
в цикле дает очень низкую производительность для более длинных строк for (int j = 0; j <= lengthOfName; j ++)
- это off-by-one- error freq == 7 && freq == 8
- логическое противоречие Я настоятельно рекомендую выполнить множество небольших, но простых упражнений для изучения основ Java. codingbat.com великолепен; их сотни, они автоматически оцениваются, поэтому вы будете знать, работает ли ваше решение должным образом или нет. В нем есть разделы по логике, строкам, массивам и т. Д.
Простейшее решение - просто иметь дубликаты в алфавите:
String алфавит = "aab";
будет иметь вероятность для a
вдвое больше, чем b
алфавит
из таблицы частот.
Просто для справки и полноты, вот "простое" (но менее эффективное) решение, предполагающее, что наличие чисел в строке не является большой проблемой:
private static final Random random = new Random();
public static String generateRandomString() {
return new BigInteger((4 + random.nextInt(3)) * 8, random).toString(36);
}
Это генерирует случайное совпадение строк [a- z0-9]
длиной 6 ~ 10 (включительно).
В вашем коде много повторений одной и той же проблемы:
if(freq == 28 && freq == 29) { ... }
Вы говорите Java выполнить условие, когда freq равен 28
И freq равен 29
. Это невозможно. Вы захотите использовать оператор OR:
if(freq == 28 || freq == 29) { ... }
Что происходит сейчас: когда freq равен любому числу внутри этих ошибочных условий, к вашей строке ничего не будет добавлено, и она станет меньше.
Вот мое решение:
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());
}
Образец вывода:
zqwloh
jefcso
spcnhxyyk
tzlobaukn
keyxkn
cllhsxybz
ieaudei
bolfzqlxrl
scpfcbztyh
thkfrybffe
nbspabxjh
Похоже, вы допустили несколько опечаток. В одном случае вы пишете
if(freq == 49 && freq == 50){ name += "j";
что на самом деле никогда не является правдой.
Условия вроде if (freq == X && freq == X + 1)
всегда false
.
Вы, вероятно, хотели использовать ||
(OR)
Готов поспорить, что вам больше не нужен ответ, но, поскольку я никогда раньше не отвечал на вопрос о переполнении стека, я подумал, что это будет хорошей разминкой.
Одна вещь, которую, казалось, упустили все остальные, - это частотный аспект вашего кода. Следующий код создаст 10 случайных слов длиной от 6 до 10 в соответствии с желаемой частотой:
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);
}
}
Теперь мой вопрос к вам: можете ли вы рассказать мне, как это работает?
JB