2016-10-19 2 views
1

Моей цель состоит в том, чтобы сформировать итерационную алфавитный/значную строку фиксированной длиной, например:Генерации алфавитной/значная строка с фиксированной длиной

aaaaaa 
aaaaab 
aaaaac 
... 
aaaaa9 
aaaaba 
... 
999999 

Он может быть легко реализован с вложенным для петель, как код ниже:

public static void main(String[] strings) { 
     Object[] array = new Object[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 
       'y', 'z', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 
     List<String> list = Lists.newArrayList(); 
     int a, b, c, d, e, f; 
     for (a = 0; a < 35; a++) { 
      for (b = 0; b < 35; b++) { 
       for (c = 0; c < 35; c++) { 
        for (d = 0; d < 35; d++) { 
         for (e = 0; e < 35; e++) { 
          for (f = 0; f < 35; f++) { 
           list.add("" + array[a] + array[b] + array[c] + array[d] + array[e] + array[f]); 
          } 
         } 
        } 
       } 
      } 
     } 
    } 

Но было бы хорошо знать, как его можно реорганизовать, чтобы иметь возможность запускать такой код в многопоточных потоках или даже некоторая библиотека уже существует для того, чтобы сгенерировать такое число.

Любая помощь будет высоко оценена.

+0

Может быть Http://codereview.stackexchange.com/ - это подходящее место для этого. – Rao

+0

, что вам нужно, пока неясно. Когда вы говорите, что фиксированная длина строки содержит либо алфавиты, либо цифры или оба? что требуется? и да, безусловно, можно оптимизировать вместо 5 вложенных циклов. –

+0

Hi Shreyas Sarvothama, спасибо за быстрые вопросы. Поэтому основная идея состоит в том, чтобы фиксировать длину строки, как показано на примере. Длина должна быть равна 6. Строка может содержать как символы в алфавитном, так и цифре – fashuser

ответ

8

Вы генерируете 35^6 = 1838265625 значений; так что вы можете переписать его с помощью одного цикла:

for (int i = 0; i < 1838265625; ++i) { 
    int ii = i; 
    int f = ii % 35; ii /= 35; 
    int e = ii % 35; ii /= 35; 
    int d = ii % 35; ii /= 35; 
    // ... 
    int a = ii % 35; 

    list.add("" + array[a] + array[b] + array[c] + array[d] + array[e] + array[f]); 
} 

Таким образом, чтобы переписать в нескольких потоках, просто разделить диапазон [0..1838265625) между вашими нитями, так что каждый поток выполняет цикл для части этого диапазона, например нить 1 делает [0..1_000_000), нить 2 делает [1_000_000..2_000_000) т.д.

Вы можете найти его проще использовать ForkJoinPool управлять расщеплению и присоединение диапазонов, а не пытаться сделать это вручную.


Конечно, я все еще думаю о предварительных Java-условиях. Вы также можете сделать это с потоками (как это было предложено GhostCat):

IntStream.range(0, 1838265625).parallelStream() 
    .map(i -> { 
     int ii = i; 
     int f = ii % 35; ii /= 35; 
     int e = ii % 35; ii /= 35; 
     int d = ii % 35; ii /= 35; 
     // ... 
     int a = ii % 35; 
     return "" + array[a] + array[b] + array[c] + array[d] + array[e] + array[f]; }) 
    .collect(someCollector); 
+0

Большое спасибо Andy за быстрый ответ, попробуем оба варианта с ForkJoinPool и с java 8 !!! – fashuser

+0

@fashuser сначала попробуйте Java 8. –

+2

@ AndyTurner, Is 'i/= 35' должно быть' ii/= 35'? – chengpohi

0

Я думаю, что ваш код может быть преобразован в раствор с использованием java8 потоков. И тогда вы можете просто перейти от решения stream() к решению parallelStream().

Недостатком является то, что потоки работают только с ссылочными типами/коллекциями; поэтому вы можете потерять производительность, не используя исходные массивы char.

1

У меня нет 50 баллов для комментариев, поэтому отправляем в качестве ответа.

Зачем нужна так много вложенных петель? 2 петли было бы достаточно. Вычислить длину массива, хранить его в length

Как

for (i=0;i<length;i++) 
{ 
    for(i=0;i<6;i++) 
    { 
     //what to do 
    } 
} 
0
  • Если вы хотите, чтобы получить все перестановки 35 символов в в шести местах, я считаю, что вы получите StackOverflowException, потому что будет список с 1'838'265'625 записей с по меньшей мере 12 байтами каждый, который составляет 20 ГБ памяти.

  • Во-вторых, используйте char, потому что ints имеет 4 байта, а char - всего 2 (unicode).

  • Наконец, в конкатенациях int будет отправляться в Integer и попытаться применить к char, и я думаю, что вы получите ASCII-представление этого int (например.1 является «началом заголовка», Непечатаемый характер)

  • Если и хочет ограниченного генератор случайных слов фиксированной длины, то вы можете использовать

private static final String[] array = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", 
      "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; 

public List<String> randomWords(int numOfWords, int lengthOfWord){ 
    List<String> list = new ArrayList<>(); 
    for(int i = 0; i < numberOfWords; i++) 
     list.add(randomWord(lengthOfWord)); 

    return list; 
} 

private String randomWord(int lengthOfWord){ 
    Random rand = new Random(); 
    StringBuilder sb = new StringBuilder(); 
    for(int i = 0; i < lengthOfWord; i++){ 
     sb.append(array[rand.nextInt(35)]); 
    } 
    return sb.toString(); 
} 
+0

Подсказка: ответы без каких-либо объяснений ... просто не очень хороший подход. Помогать людям гораздо больше, чем просто отбрасывать код на них! – GhostCat

+0

Зачем вводить случайность? OP не запрашивает «некоторые» значения, он запрашивает * все * значения. –

+0

Да, я знаю об этом, но мой премьер-министр остановил меня в середине написания ответа. Я представляю случайность, потому что понимаю, что у него нет действительной цели из-за нехватки памяти. – Zildyan

Смежные вопросы