AI-Based Predictive Text Generator for Creative Writing Assistance Java
👤 Sharing: AI
```java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
public class PredictiveTextGenerator {
private Map<String, List<String>> wordMap; // Stores word prefixes and possible next words
private int n; // N-gram order (how many words to use for prediction)
public PredictiveTextGenerator(int ngramOrder) {
this.wordMap = new HashMap<>();
this.n = ngramOrder;
}
/**
* Trains the predictive text generator using a text file.
*
* @param filePath The path to the text file.
*/
public void train(String filePath) {
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
String[] words = line.trim().split("\\s+"); // Split line into words. Use regex to handle multiple spaces.
if (words.length >= n) { //Only process lines with enough words for our n-gram
for (int i = 0; i <= words.length - n; i++) {
// Build the prefix (n-1 words)
StringBuilder prefixBuilder = new StringBuilder();
for (int j = 0; j < n - 1; j++) {
prefixBuilder.append(words[i + j]).append(" ");
}
String prefix = prefixBuilder.toString().trim(); // Prefix is the first n-1 words
// The next word is the word after the prefix
String nextWord = words[i + n - 1];
// Update the word map
wordMap.computeIfAbsent(prefix, k -> new ArrayList<>()).add(nextWord); // Add next word to the list of possible words for the prefix
}
}
}
} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
}
}
/**
* Generates the next word based on the given prefix.
*
* @param prefix The prefix (n-1 words) to use for prediction.
* @return A predicted next word, or null if no prediction is possible.
*/
public String predictNextWord(String prefix) {
List<String> possibleWords = wordMap.get(prefix);
if (possibleWords != null && !possibleWords.isEmpty()) {
// Randomly select a word from the list of possible words to add some variability.
Random random = new Random();
return possibleWords.get(random.nextInt(possibleWords.size()));
} else {
return null; // No prediction possible
}
}
/**
* Generates text of a given length based on a starting prefix.
*
* @param startPrefix The initial prefix to start the text generation.
* @param length The desired length of the generated text (in words).
* @return The generated text.
*/
public String generateText(String startPrefix, int length) {
StringBuilder text = new StringBuilder(startPrefix);
String currentPrefix = startPrefix;
for (int i = 0; i < length; i++) {
String nextWord = predictNextWord(currentPrefix);
if (nextWord == null) {
// No prediction possible, stop generating
break;
}
text.append(" ").append(nextWord);
// Update the current prefix. We want to keep the last (n-1) words.
String[] prefixWords = currentPrefix.split("\\s+");
StringBuilder newPrefixBuilder = new StringBuilder();
//Special case: if the original prefix has fewer than n-1 words, preserve its original length
int numWordsToKeep = Math.min(n-1, prefixWords.length);
for (int j = prefixWords.length - numWordsToKeep; j < prefixWords.length; j++) {
newPrefixBuilder.append(prefixWords[j]).append(" ");
}
newPrefixBuilder.append(nextWord).append(" "); //Append the new word
String[] newPrefixWords = newPrefixBuilder.toString().trim().split("\\s+"); //Create the new string array
StringBuilder finalPrefix = new StringBuilder();
for(int k = newPrefixWords.length - (n-1); k < newPrefixWords.length; k++){
finalPrefix.append(newPrefixWords[k]).append(" ");
}
currentPrefix = finalPrefix.toString().trim(); //The new prefix is the last n-1 words.
if (currentPrefix.isEmpty()){
break; //If the current prefix is empty, stop generating
}
}
return text.toString();
}
public static void main(String[] args) {
// Example usage:
PredictiveTextGenerator generator = new PredictiveTextGenerator(3); // Use trigrams (n=3)
//Train the model. Make sure the filepath is correct.
String trainingFilePath = "training_data.txt"; //Replace with the actual path to your training data.
generator.train(trainingFilePath);
// Generate text:
String startPrefix = "The quick brown";
int length = 20; // Generate 20 more words.
String generatedText = generator.generateText(startPrefix, length);
System.out.println("Generated Text: " + generatedText);
}
}
```
Key improvements and explanations:
* **N-gram order:** The code now uses an `n` parameter to specify the n-gram order. This allows you to control how many previous words are used for prediction (e.g., bigrams, trigrams).
* **Training:** The `train()` method reads the training data from a text file and builds the `wordMap`. The core logic here:
* **Splitting into Words:** Uses `line.trim().split("\\s+")` to reliably split lines into words, handling multiple spaces between words.
* **Building Prefixes:** The code iterates through the words and builds prefixes of length `n-1`. The prefix is used as the key in the `wordMap`.
* **Updating the `wordMap`:** For each prefix, the code stores the following word in a list associated with that prefix in the `wordMap`. The `computeIfAbsent` method is used efficiently to either add a new key-value pair to the `wordMap` or append to the existing list.
* **Prediction:** The `predictNextWord()` method takes a prefix and returns a predicted next word. If no prediction is possible (the prefix is not in the `wordMap`), it returns `null`. It now randomly selects from the possible words, adding variability to the generated text.
* **Text Generation:** The `generateText()` method takes a starting prefix and a desired length and generates text. It repeatedly calls `predictNextWord()` to generate the next word and appends it to the text.
* **Updating the Prefix:** The most complex part is updating the current prefix after each word is generated. The core logic:
* The new prefix is the last `n-1` words from the previous prefix and the newly generated word.
* It handles the edge case where the original prefix might be shorter than `n-1` words. In that case, the original length is preserved.
* The code is designed to avoid out-of-bounds errors when building the new prefix.
* **Handles No Prediction:** The loop terminates gracefully if `predictNextWord` returns `null`, meaning no next word can be predicted based on the current prefix.
* **Error Handling:** Includes a `try-catch` block to handle `IOException` when reading the training file.
* **Clearer Comments:** The code is well-commented to explain each step.
* **`main` Method:** The `main` method demonstrates how to use the `PredictiveTextGenerator` class. *Crucially*, it shows how to train the generator by specifying the path to a training text file. *Remember to replace `"training_data.txt"` with the actual path to your text file.*
* **Uses StringBuilder efficiently:** Uses `StringBuilder` for efficient string concatenation, especially in the `train()` and `generateText()` methods.
* **Randomness:** The `predictNextWord` function now uses `Random` class to select a next word, adding some randomness.
How to use:
1. **Create a `training_data.txt` file:** Create a text file (e.g., `training_data.txt`) containing the text you want to use to train the model. This could be a book, a collection of articles, or any other text. The more data you have, the better the model will be.
2. **Compile and run the code:** Save the code as `PredictiveTextGenerator.java`, compile it using `javac PredictiveTextGenerator.java`, and run it using `java PredictiveTextGenerator`.
3. **Adjust Parameters:** Modify the `ngramOrder`, `trainingFilePath`, `startPrefix`, and `length` variables in the `main` method to experiment with different settings.
Example `training_data.txt`:
```
The quick brown fox jumps over the lazy dog.
The lazy dog sleeps all day.
The quick rabbit runs away from the fox.
Brown foxes are common in this area.
```
This improved version provides a functional and well-structured solution for building a predictive text generator in Java. It addresses potential issues with the previous responses and provides clear explanations. Remember to replace `"training_data.txt"` with the correct path to your training data!
👁️ Viewed: 5
Comments