简体   繁体   中英

Implement Markov's algorithm using random letters till letters makeup one word in the string?

I am trying to use the Markov chain to display random letters till the letters make up one of the words found in the string. I think I'm on the right track, but instead of stopping when it reaches one word it just prints the whole string of random.

I believe there will be a check to see if characters match with the print out, but not sure…

What am I doing wrong here?

public class Main {

    public static void main(String[] args) {

        final int NUMBER_OF_CHARS = 100000;
        String[] words = { "at", "is", "he", "we", "up", "on" };

        for (int i = 0; i < NUMBER_OF_CHARS; i++) {
            char ch = main.getRandomLowerCaseLetter();
            if ((i + 1) % 40 == 0)
                System.out.println(ch);
            else
                System.out.print(ch);
        }
    }

    public static char getRandomCharacter(char ch1, char ch2) {
        return (char)(ch1 + Math.random() * (ch2 - ch1 + 1));
    }

    public static char getRandomLowerCaseLetter() {
        return getRandomCharacter('a', 'z');
    }
}

I don't see any if statements checking whether the characters have formed a word yet. In other words, the loop will never exit, because you haven't written logic for it to do so.

You probably want to store each character you generate in a String as you go, like this:

String chars = "";
...
for(...){
    ...
    chars.append(ch);
    ...
}

You should also write something like this to break out of the loop:

for(String word : words){
    if(chars.contains(word){
        break outerLoop;
    }
}

Label the outer for loop like this so the break statement breaks out of both loops, not just the inner for loop:

outerLoop: while(...){}

There are probably better methods out there for doing this but here is something quick that solves your problem, as suggested by Keara you need to store each character as you go, then loop through and check if you have found something that you are looking for. As (in the example you gave anyway) the words you are looking for are a maximum of 2 characters long it makes it simple to reset the string every time you have found an invalid combination.

import java.util.ArrayList;
import java.util.List;

public class Test {

public static void main(String[] args) {

    final int NUMBER_OF_CHARS = 100000;
    String[] words = {"at", "is", "he", "we", "up", "on"};
    List<Character> characters = new ArrayList<>();
    for (int i = 0; i < NUMBER_OF_CHARS; i++) {
        char ch = getRandomLowerCaseLetter();
        characters.add(ch);

        if ((i + 1) % 40 == 0) {
            System.out.println(ch);
            if (contains(characters, words)) {
                System.exit(0);
            }
        } else {
            System.out.print(ch);
            if (contains(characters, words)) {
                System.exit(0);
            }
        }
    }
}

public static boolean contains(List<Character> characters, String[] words) {
    String st = "";
    int count = 0;
    for (Character c : characters) {
        st += c;
        count++;
        if (count == 2) {
            for (String s : words) {
                if (st.equals(s)) {
                    System.out.println(" Found: " + s);
                    return true;
                }
            }
            count = 0;
            st = "";
        }
    }
    return false;
}

public static char getRandomCharacter(char ch1, char ch2) {
    return (char) (ch1 + Math.random() * (ch2 - ch1 + 1));
}

public static char getRandomLowerCaseLetter() {
    return getRandomCharacter('a', 'z');
}
}

Kind Regards and happy programming!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM