J'ai besoin de générer trois lignes de texte (essentiellement du jibberish) qui ont chacune 60 caractères, y compris un retour à la fin de chaque ligne. Les lignes sont générées à partir d'un dictionnaire de mots de différentes longueurs (typiquement 1-8 caractères). Aucun mot ne peut être utilisé plus d'une fois, et les mots doivent être séparés par des espaces. Je pense que c'est essentiellement un problème de bin-emballage.Comment générer des lignes de texte aléatoires d'une longueur donnée à partir d'un dictionnaire de mots (problème bin-packing)?
L'approche que j'ai prise jusqu'ici est de créer un hashMap des mots, groupés par leurs longueurs. Je choisis ensuite une longueur aléatoire, tire un mot de cette longueur de la carte et l'ajoute à la fin de la ligne que je suis en train de générer, en tenant compte des espaces ou d'un retour dur. Cela fonctionne environ la moitié du temps, mais l'autre moitié du temps je suis coincé dans une boucle infinie et mon programme se bloque. Un problème que je rencontre est celui-ci: comme j'ajoute des mots aléatoires aux lignes, les groupes de mots d'une longueur donnée peuvent devenir épuisés. C'est parce qu'il n'y a pas nécessairement le même nombre de mots de chaque longueur dans le dictionnaire, par exemple, il peut y avoir seulement un mot avec une longueur de 1. Donc, je pourrais avoir besoin d'un mot d'une longueur donnée, mais il n'y a plus tous les mots de cette longueur disponibles.
Voici un résumé de ce que j'ai jusqu'à présent. Je travaille en ActionScript, mais j'aimerais avoir un aperçu de ce problème dans n'importe quelle langue. Merci d'avance.
dictionary // map of words with word lengths as keys and arrays of corresponding words as values
lengths // array of word lengths, sorted numerically
min = lengths[0] // minimum word length
max = lengths[lengths.length - 1] // maximum word length
line = ""
while (line.length < 60) {
len = lengths[round(rand() * (lengths.length - 1))]
if (dictionary[len] != null && dictionary[len].length > 0) {
diff = 60 - line.length // number of characters needed to complete the line
if (line.length + len + 1 == 60) {
// this word will complete the line exactly
line += dictionary[len].splice(0, 1) + "\n"
}
else if (min + max + 2 >= diff) {
// find the two word lengths that will complete the line
// ==> this is where I'm having trouble
}
else if (line.length + len + 1 < 60 - max) {
// this word will fit safely, so just add it
line += dictionary[len].splice(0, 1) + " "
}
if (dictionary[len].length == 0) {
// delete any empty arrays and update min and max lengths accordingly
dictionary[len] = null
delete dictionary[len]
i = lengths.indexOf(len)
if (i >= 0) {
// words of this length have been depleted, so
// update lengths array to ensure that next random
// length is valid
lengths.splice(i, 1)
}
if (lengths.indexOf(min) == -1) {
// update the min
min = lengths[0]
}
if (lengths.indexOf(max) == -1) {
// update the max
max = lengths[lengths.length - 1]
}
}
}
}
Nous vous remercions de votre réponse. J'ai mis à jour ma question ci-dessus avec plus de détails. Je ne peux pas utiliser un mot plus d'une fois, alors je supprime les mots au fur et à mesure que je les utilise. En conséquence, il n'y a aucune garantie qu'il y aura un mot de la longueur exacte nécessaire quand j'arriverai à la fin de la ligne. – Bryan