I wrote up a program that can sort words and determine any anagrams. I want to generate an array of random strings so that I can test my method's runtime.
public static String[] generateRandomWords(int numberOfWords){
String[] randomStrings = new String[numberOfWords];
Random random = Random();
return null;
}
(method stub)
I just want lowercase words of length 1-10. I read something about generating random numbers, then casting to char or something, but I didn't totally understand. If someone can show me how to generate random words, then I should easily be able to just use a for loop to insert the words into the array. Thanks!
Do you need actual English words, or just random strings that only contain letters a-z?
If you need actual English words, the only way to do it is to use a dictionary, and select words from it at random.
If you don't need English words, then something like this will do:
public static String[] generateRandomWords(int numberOfWords)
{
String[] randomStrings = new String[numberOfWords];
Random random = new Random();
for(int i = 0; i < numberOfWords; i++)
{
char[] word = new char[random.nextInt(8)+3]; // words of length 3 through 10. (1 and 2 letter words are boring.)
for(int j = 0; j < word.length; j++)
{
word[j] = (char)('a' + random.nextInt(26));
}
randomStrings[i] = new String(word);
}
return randomStrings;
}
RandomStringUtils from commons-lang
Why generating random words? When you can use some dictionaries.
If you want to generate random words of a given length, you'll either need an algorithm to determine if a given string is a word (hard), or access to a word list of all the words in a given language (easy). If it helps, here's a list of every word in the Scrabble dictionary.
Once you have a list of all words in a language, you can load those words into an ArrayList or other linear structure. You can then generate a random index into that list to get the random word.
You can call this method for each word you want to generate. Note that the probability of generating anagrams should be relatively low though.
String generateRandomWord(int wordLength) {
Random r = new Random(); // Intialize a Random Number Generator with SysTime as the seed
StringBuilder sb = new StringBuilder(wordLength);
for(int i = 0; i < wordLength; i++) { // For each letter in the word
char tmp = 'a' + r.nextInt('z' - 'a'); // Generate a letter between a and z
sb.append(tmp); // Add it to the String
}
return sb.toString();
}
If you want random words without using a dictionary...
Make a list of all the letters you want possible in your words
Generate a random index to pick out a letter from the list
Repeat until you have your desired word length
Repeat these steps for the number of words you want to generate.
Related
I am attempting to write a program that will find all the words that can be constructed from it using a dictionary which has been loaded into an arrayList from a file. sowpodsList is the dictionary stored as an arrayList. I want to iterate through each word in the dictionary and then compare it to the string. Being that the string is just a random collection of words how do I go about achieving this ?
Input: asdm
Output: a, mad, sad .... (any word which matches in the dictionary.)
for (int i = 0; i < sowpodsList.size(); i++) {
for (int j = 0; j < sowpodsList.get(i).length(); j++) {
if (sowpodsList.get(i).charAt(j) == )
;
}
}
You can search if the count of each character of each word in the dictionary is equal to the input's character count.
ArrayList <String> matches = new ArrayList <String> ();
// for each word in dict
for(String word : sowpodsList) {
// match flag
Boolean nonMatch = true;
// for each character of dict word
for( char chW : word.toCharArray() ) {
String w = Character.toString(chW);
// if the count of chW in word is equal to its count in input,
// then, they are match
if ( word.length() - word.replace(w, "").length() !=
input.length() - input.replace(w, "").length() ) {
nonMatch = false;
break;
}
}
if (nonMatch) {
matches.add( word );
}
}
System.out.println(matches);
Sample output: (dict file I used is here: https://docs.oracle.com/javase/tutorial/collections/interfaces/examples/dictionary.txt)
Input: asdm
Matches: [ad, ads, am, as, dam, dams, ma, mad, mads, mas, sad]
If I were you I'd change the way you store your dictionary.
Given that the string input has random letters in it, what I'd do here is store all words of your dictionary in a SortedMap<String, char[]> (a TreeMap, to be precise) where the keys are the words in your dictionary and the values are characters in this word sorted.
Then I'd sort the characters in the input string as well and go for that (pseudo code, not tested):
public Set<String> getMatchingWords(final String input)
{
final char[] contents = input.toCharArray();
Arrays.sort(contents);
final int inputLength = contents.length;
final Set<String> matchedWords = new HashSet<>();
char[] candidate;
int len;
int matched;
for (final Map.Entry<String, char[]> entry: dictionary.entrySet()) {
candidate = entry.getValue();
// If the first character of the candidate is greater
// than the first character of the contents, no need
// to continue (recall: the dictionary is sorted)
if (candidate[0] > contents[0])
break;
// If the word has a greater length than the input,
// go for the next word
len = candidate.length;
if (len > inputLength)
continue;
// Compare character by character
for (matched = 0; matched < len; matched++)
if (candidate[matched] != contents[matched])
break;
// We only add a match if the number of matched characters
// is exactly that of the candidate
if (matched == len)
matchedWords.add(entry.getKey());
}
return matchedWords;
}
private static int commonChars(final char[] input, final char[] candidate)
{
final int len = Math.min(input.length, candidate.length);
int ret = 0;
for (int i = 0; i < len; i++) {
if (input[i] != candidate[i])
break;
ret++;
}
return ret;
}
With a trie: that would also be possible; whether it is practical or not however is another question, it depends on the size of the dictionary.
But the basic principle would be the same: you'd need a sorted character array of words in your dictionary and add to the trie little by little (use a builder).
A trie node would have three elements:
a map where the keys are the set of characters which can be matched next, and the values are the matching trie nodes;
a set of words which can match at that node exactly.
You can base your trie implementation off this one if you want.
Go for TRIE implementation.
TRIE provides the fastest way for searching over an Array of large collection of words.
https://en.wikipedia.org/wiki/Trie
What you need to do is to insert all words into the trie data structure.
Then just need to call search function in Trie to get the boolean match info.
There are two ways to do it. The best way depends on the relative size of the data structures.
If the dictionary is long and the list of letters is short, it may be best to sort the dictionary (if it is not already), then construct all possible words by permuting the letters (removing duplicates). Then do a binary search using string comparison for each combination of letters to see if it is a word in the dictionary. The tricky part is ensuring that duplicate letters are used only when appropriate.
If the list of letters is long and the dictionary is short, another way would be simply to count the number of letters in the input string: two a's, one s, one m, etc. Then for each dictionary word, if the number of each individual letter in the dictionary word does not exceed those in the input string, the word is valid.
Either way, add all words found to the output array.
For my program, the input from the user will be something like this:
{1,2,3} {1,2} {4,5,6}
There can be multiple { } with any number of ... numbers inside.
I already made a 2 dimensional array with an array for each sequence of numbers: {}
I am having troubling splitting them into their respective arrays so it will be something like this:
Array[0] = ["1","2","3"]
Array[1] = ["1","2"]
Array[2] = ["4","5","6"]
How would i split it like that? i dont know if i can split this string into n number of strings since the number of sequences depends on user.
Split the string on " " (space), and from there remove the curly brackets (perhaps take a substring, from index 1 to index length-1). Then split on comma. That should return a string array containing numbers. From there parse the strings to integers, and store in an integer array.
This code will help you
public class T {
public static void main(String[] args) {
String s = "{1,2,3} {1,2} {4,5,6}";
String[] mainArray = s.split(" ");
String[][] result = new String[mainArray.length][];
int count = 0;
for (String t : mainArray) {
result[count] = t.split(",");
count++;
}
}
}
var x = "{1,2,3} {1,2} {4,5,6}";
var y = x.split(" ");
var k =[];
for(var i = 0; i < y.length; i++){
k.push((y[i].substring(1,y[i].length-1)).split(","));
}
Well, this be how you would do it in javascript, algorithm.(my bad mis-read the tag)
K will be the final array.
Create a collection of arrays (of the type the input arrays will be, if known).
Split the array on "{".
With the resulting array, you remove the "}" from each string and split it on ",".
Then iterate over the resulting string array, parsing its contents and building an array of your entry type.
Finally, add that array to your collection.
This assumes there are no sub-arrays, true for your sample input. It does not assume the user added spaces between the given arrays, however; that is something I wouldn't trust a user to remember.
I have to generate a sequence of strings combination starting with some fixed bits at the beginning, for example,
String password = "abc-----"
Here, the first three characters remain the same for every combination, only the characters after that have to change,
I need various combinations of this string like
abca
abcb
abcc
-----
abcaa
abcab
---- so on
using any loop, so that within the same loop i need to compare this with other input string and output the string, if both match.
How to generate this sequence or various combinations of strings using a loop in Java or in general ?
//update, sorry, i forgot to post what i tried:
i am doing it using nested for loops such as,
for(char i='a'; i<'z'; i++) {
for(char j='a'; j<'z'; j++) {
String password = "abc" + i + j ;
}
}
Is there any more efficient way to do this ?
if you want to generate a random string then you can use: (here i have included numbers also in my random string generation, if you dont want to use numbers then you can remove from sample variable)
public String getRandomString(String prefix, int length) {
String sample = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Random random = new Random();
StringBuilder sb = new StringBuilder();
sb.append(prefix);
for (int index = 0; index < length; index++) {
sb.append(sample.charAt(random.nextInt(sample.length())));
}
return sb.toString();
}
So I want to generate a random string but only want certain characters to be the string (Only ones that can be used in a file name to be hosted so something like www.example.com/HERE.EXTENTION).
So how can I make a random string that is a length that I want with only certain letters I want.
I know I can do a for look from the length, and then use the random number and cast that to a char and add it to a string. But I don't want characters that I don't want to be added and going through a loop with all that I don't want because that would take too long.
Use this quick method:
String genRand(int length){
Random rand=new Random();
String possibleLetters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.";
StringBuilder sb = new StringBuilder(length);
for(int i = 0; i < length; i++)
sb.append(possibleLetters.charAt(rand.nextInt(possibleLetters.length())));
return sb.toString();
}
Edit possibleLetters to include the characters you want. Note that \ and newlines must be escaped.
Store all your accepted letters in an array, then generate a random number between 0 and the length of this array N times, to get N indices of a letter in the array. Concatenate the letters.
EDIT:
Note that if your goal is to generate unique names, random is not the solution. A random doesn't guarantee uniqueness.
Other than the two answers -
You can have it like <yourChoiceOfName>-<currentTime>.yourext. This way the chances of two files with the same name is lesser.
The currenttime could include milliseconds.
In this case you have a known length i.e. length of yourChoiceOfName + length of currentTime + lenght of yourext.
I have split a string into an array every time a letter appeared, however I now want to split each string in the array into more arrays went another letter appears, adding an array below each split with the letter removed.
Here is my code:
private String input = "118u121u23n24"
private int y = 0;
private String[] split_main = new String[100];
private void split_u(){
String[] split = input.split("u");
for(int x=0; split.length>x; x++){
split_main[y] = split[x];
if(split.length>x+1)
split_main[y+1] = "+";
y +=2;
}
This splits my string into an array like this - creates a new array every time "u" appears and adds a plus
118
+
121
+
23n24
I now want to go through each of these arrays and look for the letter n and put it on a separate line so this will be the new array. However every time I have tried this I have got errors because I don't seem to be able to use the Split method again on the array. If using split is not possible then is there another way to do it?
118
+
121
+
23
n
24
Thanks in advance for any help.
Try this
String[] split = input.split("u|n");
u|n means that split string with by u or n, simply split string by two separator
while you want to add different separator in two levels you should write code like this.
String input = "118u121u23n24";
String[] s2;
ArrayList<String> main = new ArrayList<String>();
String[] split = input.split("u");
for(int x=0; split.length>x; x++){
s2 = split[x].split("n");
for(int k=0; k<s2.length; k++){
main.add(s2[k]);
if(s2.length>k+1)
main.add("n");
}
if(split.length>x+1)
main.add("+");
}
// print main array to test
for(int i=0;i<main.size();i++)
System.out.println(main.get(i));
I'd suggest that you simply split on all the letters at once, using a regex:
String[] split = input.split("(+|n)");
If you require the intermediate steps, then the only way to do it is to iterate through the first split, building an array of results of splitting on the second letter. If you want to do this for multiple split patterns (not just "+" and "n"), you will need a general purpose procedure. Here's sample code:
/**
* Replaces one element of a list of strings with the results of
* splitting that element with a given pattern. A copy of the pattern
* is inserted between the elements of the split.
* #param list The list of elements to be modified
* #param pattern The pattern on which to split
* #param pos The position of the element to split
* #return The number of additional elements inserted. This is the amount by
* which the list grew. If the element was not split, zero is returned.
*/
int splitElements(List<String> list, String pattern, int pos) {
String[] split = list.get(pos).split(pattern);
if (split.length > 1) {
list.set(pos++, split[0]);
for (int i = 1; i < split.length; ++i) {
list.add(pos++, pattern);
list.add(pos++, split[i]);
}
} // else nothing to do
return (split.length << 1) - 1;
}
Then you would call this with each character with which you want to split:
private String input = "118u121u23n24";
private ArrayList<String> split_main = new ArrayList<String>();
split_main.add(input);
splitElements(split_main, "+", 0);
for (int i = 0; i < len; ++i) {
i += splitElements(split_main, "n", i);
}
It's possible. Use List instead of array to make inserting new items easy.
If you want arrays only, do it in two passes: first, iterate over input and count how many more cells you need because of n, then create new array of proper size and copy input contents to it, splitting along the way.