xirb22
xirb22

Reputation: 13

Java word generating algorithm

I want to create a word generator, but in a way it almost seems like a numerical system. Hex goes from 0 to f, this algorithm should go from a to z. So the word that is created goes like this (every - means a new word):

a - b - c - d - ... - z - aa - ab - ac - ad - ... - ba - bb - bc - ...

Each word is for example stored in a file, so the file would read:

a  
b  
c  
d  
...  
z  
aa  
ab  
ac  
...  

I think this is possible with a lot of nested for loops and ifs, but is there a simpler way to do this? You don't have to tell me the whole algorithm, but a nudge in the right direction is much appreciated.

Upvotes: 1

Views: 2532

Answers (9)

letrait
letrait

Reputation: 11

Here is an implementation that output the first 1000 words:

for (int n = 0; n < 1000; n++) {
   String s = Long.toString(n, 26);
   StringBuilder word = new StringBuilder();
   for (int i = 0; i < s.length(); i++) {
       int value = Character.digit(s.charAt(i), 26);
       // if it is not the right most caracter, then '1' is map to 'a', if not,
       // '0' is map to 'a'
       value = value + (i < s.length() - 1 ? -1 : 0);
       word.append(Character.toChars('a' + value)[0]);
   }
   System.out.println(n + " -> " + word.toString());
}

Upvotes: 0

barak1412
barak1412

Reputation: 1160

I would do this:

Input n - number of words you want to generate, [I,J] - the range for the words length.

The algorithm:

  • Do n times:

    • i <- random number between I and J.
    • Do i times: (0 <= j <= i-1)
      • Word[j] = random char between 'a' and 'z'
    • Add Word to result
  • Return result

Upvotes: 0

cl-r
cl-r

Reputation: 1264

    final char[] tabC = "abcdefghijklmnopqrstuvwxyz".toCharArray();
    for (final char c1 : tabC) {
        System.out.println(c1 + "\t" + c1);
        for (final char c2 : tabC) {
            System.out.println(Character.toString(c1)
                + Character.toString(c2) + "\t" + (c1 + (c2 << 6)));
        }
    }

Just verify if <<6 is sufficient to avoid collision(have to Strings for one numbe)

output

a   97
aa  6305
ab  6369
ac  6433
. . .
ar  7393
as  7457
az  7905
b   98
ba  6306
bb  6370
bc  6434
bd  6498
. . . 


rz  7922
s   115
sa  6323
sb  6387
sc  6451
sd  6515
se  6579

Upvotes: 0

amit
amit

Reputation: 178461

If you are looking for creating a single random word, then follow the next steps:

  1. Populate an array of chars: char[] arr = { 'a', 'b', ... , 'z'}
  2. get a random integer that denotes the size of the string.
  3. initialize an empty string s
  4. iterate from 0 to the drawed length, draw a number in range [0,arr.length) let it be x, and append arr[x] to the string s.

If you are looking for all possibilities, you are looking for all combinations, and the simplest way to do it in my opinion is using recursion. The idea is to "guess" the first char, and run the recursion on the suffix of the string - repeat this for all first possibilities of first char, and you get all combinations.

Pseudo code:

getCombinations(set,idx,length,current):
  if (idx == length):
    set.add(copy(current))
    return
  for each char c:
    current[idx] = c //setting the next char
    getCombinations(set,idx+1,length,current) //invoking recursively on smaller range

invoke with getCombinations([],0,length,arr) where [] is an empty set which will hold the results, length is the length of the combinations generated, and arr is an empty array.
To get combinations smaller then length you can either add also substrings during the process or to invoke with smaller length.

Note that the number of combinations is exponential in the length of the word, so it will consume a lot of time.

Upvotes: 2

Arpssss
Arpssss

Reputation: 3858

I don't know whether you can use any random integer function library or not. However, I am giving you a simple pseudo code based on that:

1) Generate a Random Number I from 1 to 10.
2) For J = 0 to I
byte array[j] =  (byte) Generate a Random Number from 0 to 128.
3) For J = 0 to I
String st = st + (char) byte array[j]

String will be a random word. Simple. But, I don't know whether acceptable or not.

Upvotes: 1

George Karanikas
George Karanikas

Reputation: 1244

Lets suppose that you know the length of the list and the 'words' are again of random length and of totally random. You can then do something like the following (it prints the words, you can write them on a file instead):

import java.util.Random;
...
String alphabet = "qwertyuioplkjhgfdsazxcvbnm";
Random r = new Random();

for(int i = 0; i < list_length; i++) {
  int word_size = r.nextInt(word_max_length);
  String word = "";
  for(int j = 0; j < word_size; j++) {
    word += alphabet.charAt(r.nextInt(alphabet.length()));
  }
  System.out.println(word);
}

Upvotes: 0

amon
amon

Reputation: 57630

Create a function that maps integers to character sequences. ie:

 0  -> a
 1  -> b
 ...
 26 -> aa

etc. You can use that to create a specific word or a list of words iteratively.

Inside your algorithm you will be using modulus %26 a lot…

Upvotes: 1

CloudyMarble
CloudyMarble

Reputation: 37566

You need to define how long are your words, otherwise this would be infinitve.

This is called Combinatorics in math, take a look here you can choose which algorthm suits your needs.

Upvotes: 0

Roman Saveljev
Roman Saveljev

Reputation: 2594

Nudge served:

Yes, it is possible. You run single for-loop and then convert every counter value to base 26. Then every digit in your new number will code one letter. Please see here on how to convert numbers to arbitrary base. (Sorry for ads overrun page)

Upvotes: 0

Related Questions