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