Java 检测包含空格的单词是否有效

Java 检测包含空格的单词是否有效,java,regex,string,Java,Regex,String,我正在开发一款基于手机的文字游戏,玩家可以选择使用相当多的空格(代表任何字母) 我把所有可能的单词存储在一个哈希集中,这样,当一个单词有一个空格时,检测它是否有效,只不过是通过字母表的循环,用字母替换空白,测试单词。我有一个递归调用,所以它可以处理任意数量的空格。代码如下: public boolean isValidWord(String word) { if (word.contains(" ")){ for (char i = 'A'; i <= 'Z'; i

我正在开发一款基于手机的文字游戏,玩家可以选择使用相当多的空格(代表任何字母)

我把所有可能的单词存储在一个哈希集中,这样,当一个单词有一个空格时,检测它是否有效,只不过是通过字母表的循环,用字母替换空白,测试单词。我有一个递归调用,所以它可以处理任意数量的空格。代码如下:

public boolean isValidWord(String word) {
    if (word.contains(" ")){
        for (char i = 'A'; i <= 'Z'; i++) {
            if (isValidWord(word.replaceFirst(" ", Character.toString(i))))
                return true;
        }

        return false;
    }
    else
        return wordHashSet.contains(word);
}
公共布尔值isValidWord(字符串字){
if(word.contains(“”){

for(char i='A';i有点难看,但我想相当快的方法是创建一个包含所有有效单词的字符串,如下所示:

WORD1
WORD2
WORD3
等等


然后使用类似正则表达式的
(^ |\n)a[a-Z]PL[a-Z]\n
(即用
[a-Z]
替换所有空格),并在该字符串上进行匹配。

一种难看的方法,但我想相当快的方法是创建一个包含所有有效单词的字符串,如下所示:

WORD1
WORD2
WORD3
等等


然后使用类似正则表达式的
(^ |\n)a[a-Z]PL[a-Z]\n
(即,将所有空格替换为
[a-Z]
),并在该字符串上进行匹配。

一种非常快速的方法,尽管实现起来有点困难,但将单词存储在Trie-

trie是一种树结构,它在每个节点中包含一个char和一个指向下一个节点的指针数组

如果没有空格,这将很容易-只需遵循trie结构,您可以在线性时间内检查它。当您有一个空格时,您将有一个循环来搜索所有可能的路由

如果您不熟悉尝试,这听起来可能会很复杂和困难,但如果您陷入困境,我可以帮助您编写一些代码

编辑:

好的,这里有一些c#代码,可以用Trys解决您的问题,我认为您在JAVA中转换它不会有问题。如果您这样做了,请留下评论,我将提供帮助

Trie.cs

public class Trie
{

    private char blank = '_';

    public Node Root { get; set; }

    public void Insert(String key)
    {
        Root = Insert(Root, key, 0);
    }

    public bool Contains(String key)
    {
        Node x = Find(Root, key, 0);
        return x != null && x.NullNode;
    }

    private Node Find(Node x, String key, int d)
    { // Return value associated with key in the subtrie rooted at x.
        if (x == null)
            return null;

        if (d == key.Length)
        {
            if (x.NullNode)
              return x;
            else
              return null;
        }

        char c = key[d]; // Use dth key char to identify subtrie.

        if (c == blank)
        {
            foreach (var child in x.Children)
            {
                var node = Find(child, key, d + 1);
                if (node != null)
                    return node;
            }

            return null;
        }
        else
            return Find(x.Children[c], key, d + 1);
    }

    private Node Insert(Node x, String key, int d)
    { // Change value associated with key if in subtrie rooted at x.
        if (x == null) x = new Node();
        if (d == key.Length)
        {
            x.NullNode = true;
            return x;
        }

        char c = key[d]; // Use dth key char to identify subtrie.
        x.Children[c] = Insert(x.Children[c], key, d + 1);
        return x;
    }

    public IEnumerable<String> GetAllKeys()
    {
        return GetKeysWithPrefix("");
    }
    public IEnumerable<String> GetKeysWithPrefix(String pre)
    {
        Queue<String> q = new Queue<String>();
        Collect(Find(Root, pre, 0), pre, q);
        return q;
    }

    private void Collect(Node x, String pre, Queue<String> q)
    {
        if (x == null) return;
        if (x.NullNode) q.Enqueue(pre);
        for (int c = 0; c < 256; c++)
            Collect(x.Children[c], pre + ((char)c), q);
    }
}
示例用法:

Trie tr = new Trie();
tr.Insert("telephone");
while (true)
{
     string str = Console.ReadLine();
     if( tr.Contains( str ) )
         Console.WriteLine("contains!");
     else
         Console.WriteLine("does not contain!");
}

一种非常快速的方法,尽管实现起来有点困难,但它是将您的单词存储在Trie-

trie是一种树结构,它在每个节点中包含一个char和一个指向下一个节点的指针数组

如果没有空格,这将很容易-只需遵循trie结构,您可以在线性时间内检查它。当您有一个空格时,您将有一个循环来搜索所有可能的路由

如果您不熟悉尝试,这听起来可能会很复杂和困难,但如果您陷入困境,我可以帮助您编写一些代码

编辑:

好的,这里有一些c#代码,可以用Trys解决您的问题,我认为您在JAVA中转换它不会有问题。如果您这样做了,请留下评论,我将提供帮助

Trie.cs

public class Trie
{

    private char blank = '_';

    public Node Root { get; set; }

    public void Insert(String key)
    {
        Root = Insert(Root, key, 0);
    }

    public bool Contains(String key)
    {
        Node x = Find(Root, key, 0);
        return x != null && x.NullNode;
    }

    private Node Find(Node x, String key, int d)
    { // Return value associated with key in the subtrie rooted at x.
        if (x == null)
            return null;

        if (d == key.Length)
        {
            if (x.NullNode)
              return x;
            else
              return null;
        }

        char c = key[d]; // Use dth key char to identify subtrie.

        if (c == blank)
        {
            foreach (var child in x.Children)
            {
                var node = Find(child, key, d + 1);
                if (node != null)
                    return node;
            }

            return null;
        }
        else
            return Find(x.Children[c], key, d + 1);
    }

    private Node Insert(Node x, String key, int d)
    { // Change value associated with key if in subtrie rooted at x.
        if (x == null) x = new Node();
        if (d == key.Length)
        {
            x.NullNode = true;
            return x;
        }

        char c = key[d]; // Use dth key char to identify subtrie.
        x.Children[c] = Insert(x.Children[c], key, d + 1);
        return x;
    }

    public IEnumerable<String> GetAllKeys()
    {
        return GetKeysWithPrefix("");
    }
    public IEnumerable<String> GetKeysWithPrefix(String pre)
    {
        Queue<String> q = new Queue<String>();
        Collect(Find(Root, pre, 0), pre, q);
        return q;
    }

    private void Collect(Node x, String pre, Queue<String> q)
    {
        if (x == null) return;
        if (x.NullNode) q.Enqueue(pre);
        for (int c = 0; c < 256; c++)
            Collect(x.Children[c], pre + ((char)c), q);
    }
}
示例用法:

Trie tr = new Trie();
tr.Insert("telephone");
while (true)
{
     string str = Console.ReadLine();
     if( tr.Contains( str ) )
         Console.WriteLine("contains!");
     else
         Console.WriteLine("does not contain!");
}
公共布尔值isValidWord(字符串字){
ArrayList pos=新的ArrayList();
for(int i=0;i!=word.length();i++){
如果(单词字符(i)='')位置添加(i);
}
for(字符串hashSetWord:hashSet){
用于(整数i:pos){
hashSetWord=hashSetWord.substring(0,i)+“”+hashSetWord.substring(i+1);
}
if(hashSetWord.equals(word))返回true;
}
返回false;
}
公共布尔值isValidWord(字符串字){
ArrayList pos=新的ArrayList();
for(int i=0;i!=word.length();i++){
如果(单词字符(i)='')位置添加(i);
}
for(字符串hashSetWord:hashSet){
用于(整数i:pos){
hashSetWord=hashSetWord.substring(0,i)+“”+hashSetWord.substring(i+1);
}
if(hashSetWord.equals(word))返回true;
}
返回false;
}
一个直字符串.equals(xx)足够快,但显然 不考虑空格

因此,我建议实现这个简单的解决方案,它非常接近
String.equals()
,并且考虑了空格:

public boolean isValidWord(String word) {
    if (wordHashSet.contains(word)) {
        return true;
    }
    for (String fromHashSet: wordHashSet){
        if (compareIgnoreBlanks(fromHashSet, word)) {
            return true;
        }
    }
    return false;
}

/**
 * Inspired by String.compareTo(String). Compares two String's, ignoring blanks in the String given as
 * second argument.
 * 
 * @param s1
 *            String from the HashSet
 * @param s2
 *            String with potential blanks
 * @return true if s1 and s2 match, false otherwise
 */
public static boolean compareIgnoreBlanks(String s1, String s2) {
    int len = s1.length();
    if (len != s2.length()) {
        return false;
    }

    int k = 0;
    while (k < len) {
        char c1 = s1.charAt(k);
        char c2 = s2.charAt(k);
        if (c2 != ' ' && c1 != c2) {
            return false;
        }
        k++;
    }
    return true;
}      
公共布尔值isValidWord(字符串字){
if(wordHashSet.contains(word)){
返回true;
}
for(字符串fromHashSet:wordHashSet){
if(compareIgnoreBlanks(来自hashset,word)){
返回true;
}
}
返回false;
}
/**
*灵感来源于String.compareTo(String)。比较两个字符串,忽略给定字符串中的空格
*第二个论点。
* 
*@param s1
*哈希集中的字符串
*@param s2
*带位空格的字符串
*@如果s1和s2匹配,则返回true,否则返回false
*/
公共静态布尔比较器索引(字符串s1、字符串s2){
int len=s1.length();
如果(len!=s2.length()){
返回false;
}
int k=0;
while(k
一个直字符串.equals(xx)足够快,但显然 不考虑空格

因此,我建议实现这个简单的解决方案,它非常接近
String.equals()
,并且考虑了空格:

public boolean isValidWord(String word) {
    if (wordHashSet.contains(word)) {
        return true;
    }
    for (String fromHashSet: wordHashSet){
        if (compareIgnoreBlanks(fromHashSet, word)) {
            return true;
        }
    }
    return false;
}

/**
 * Inspired by String.compareTo(String). Compares two String's, ignoring blanks in the String given as
 * second argument.
 * 
 * @param s1
 *            String from the HashSet
 * @param s2
 *            String with potential blanks
 * @return true if s1 and s2 match, false otherwise
 */
public static boolean compareIgnoreBlanks(String s1, String s2) {
    int len = s1.length();
    if (len != s2.length()) {
        return false;
    }

    int k = 0;
    while (k < len) {
        char c1 = s1.charAt(k);
        char c2 = s2.charAt(k);
        if (c2 != ' ' && c1 != c2) {
            return false;
        }
        k++;
    }
    return true;
}      
公共布尔值isValidWord(字符串字){
if(wordHashSet.contains(word)){
返回true;
}
for(字符串fromHashSet:wordHashSet){
if(compareIgnoreBlanks(来自hashset,word)){
返回true;
}
}
返回false;
}
/**
*灵感来源于String.compareTo(String)。比较两个字符串,忽略给定字符串中的空格
*第二个论点。
* 
*@param s1
*哈希集中的字符串
*@param s2
*带位空格的字符串
*@如果s1和s2匹配,则返回true,否则返回false
*/
公共静态布尔比较器索引(字符串s1、字符串s2){
int len=s1.length();
如果(len!=s2.length()){
返回false;
}
int k=0;
while(k