所以我一直试图解决这一任务,只是无法解决。
以下函数接受2个字符串,第2个(非第1个)可能包含*(星号)。
*替代字符串(空,1个字符或更多),它可以出现一次(仅在s2中)一次,两次,更多次或根本不出现,它不能与另一个*(),无需检查。
public static boolean samePattern(String s1, String s2)
如果字符串具有相同的模式,则返回true。
它必须是递归的,不能使用任何循环,静态和全局变量。
可以使用局部变量和方法重载。
只能使用以下方法:charAt(i),substring(i),substring(i, j),length()。
例子:
1:TheExamIsEasy; 2:The*xamIs*y→true
1:TheExamIsEasy; 2:Th*mIsEasy*→true
1:TheExamIsEasy; 2:*→true
1:TheExamIsEasy; 2:TheExamIsEasy→true
1:TheExamIsEasy; 2:The*IsHard→假
我尝试使用charAt逐个比较字符,直到遇到星号,然后通过比较连续的字符(i+1)与位置i处的s1字符来检查星号是否为空,如果为true-继续递归,以i+1作为s2的计数器和i作为s1的计数器;
如果为false-继续使用i+1作为两个计数器的递归。
继续此操作,直到找到另一个星号或字符串结尾。
我不知道,我的大脑迷失了方向,无法专心,没有任何指示/提示?我的方向正确吗?
另外,有消息称将使用回溯技术来解决此问题。
到目前为止,我的代码(即使从理论上讲也没做):
public static boolean samePattern(String s1, String s2) {
if (s1.equals(s2) || s2 =="*") {
return true;
}
return samePattern(s1, s2, 1);
}
public static boolean samePattern(String s1, String s2, int i)
{
if (s1.equals(s2))
return true;
if (i == s2.length() - 1) // No *'s found -- not same pattern.
return false;
if (s1.substring(0, i).equals(s2.substring(0, i)))
samePattern(s1, s2, i+1);
else if (s2.charAt(i-1) == '*')
samePattern(s1.substring(0, i-1), s2.substring(0, i), 1); // new smaller strings.
else
samePattern(s1.substring(1), s2, i);
}
寻求建议而不是整个解决方案的荣誉。
这是一些可以帮助您的Python"伪代码"
def samePattern(s1,s2):
if s2 =="*" or s1 == s2: return True
if s1 =="": return False
if s1[0] == s2[0]: return samePattern(s1[1:], s2[1:])
if s2[0] =="*": return samePattern(s1, s2[1:]) or samePattern(s1[1:], s2)
return False
这是转换代码的粗略指南
s[0] = the first character
s[1:] = the string minus the first character
第一个if中的s2=="*"真的必要吗? 并且您是否应该检查s2是否长于s1(例如,在第二个if中)?
@strager,是的,其余代码的编写方式很有必要。
非常感谢! 也感谢其他所有人,我现在明白了。 :)
当前方法的问题在于,它没有考虑*可以匹配的所有可能的子字符串。例如,samePattern(" ababababab"," a * b")应该返回true; *可以匹配字符串的第一个和最后一个字母,但不能匹配所有字符串,但是您的代码假定由于下一个字母为b,因此*匹配空字符串。
我建议将samePattern视为在寻找匹配项时"消耗"其两个输入字符串。在每个步骤中,samePattern只需要查看每个字符串的第一个字符来确定在第一个字符处是否可能匹配,如果可以,则进行递归调用以检查字符串的其余部分。技巧是知道在模式字符串中出现*时该怎么做,因为它可能会或可能不会用于匹配s1中的第一个字符。您无需查看字符串的其余部分即可决定要做什么。
由于这是家庭作业,因此我将详细弄清楚那里发生的事情,但是希望这会使您思考正确的道路。
对; 使用递归来处理减少的,更简单的输入。
在处理这种算法时,通常需要将问题分解为小块。
由于您是字符串解析,因此请逐个字符考虑解决方案。此外,由于您无法控制这些字符串的实际大小,因此请限制您在任何给定时间仅考虑字符串的第一个字符。 (嗯-一个例外)
一旦确定了要处理的字符,就需要进一步调查字符串的其余部分,然后将它们扔掉;将它们保持在周围只会增加复杂性,那么为什么要麻烦呢? (相反,如果字符完全不匹配,那么您就完成了-对吗?)
当然,这是对字符串的递归,因此您必须具有一些条件来控制失败/成功,以处理字符串的整体状态-但这不是问题的实质-检查字符串的状态函数顶部的字符串,然后继续。
我有一个算法,如果您想要一个完整的解决方案,我可以发布(11行代码,加上大括号),但是您不确定要给它一个算法,还是只是一个指针,我不确定您的消息。
自我注意:不要开始输入答案,分散注意力,然后在不检查中间时间更新的情况下完成答案。 我写了Paul Kuliniewicz所做的很多事情。 :(如果我写东西的方式在OP中引起共鸣,请留在这里。
但这不会使您的答案无效或有用。 =]
这是用c#编写的示例解决方案。很抱歉缺少评论,但我没有时间给他们:/如果明天您仍然需要它们,那么我可以写一些,但是我希望您能理解。
public static bool CompareString(string s1, string s2, bool wildCard)
{
// Both strings are empty
if ((s1.Length == 0) && (s2.Length == 0)) return true;
// Second string is empty and there is wildCard character
if (s2.Length == 0 && wildCard) return true;
//First string is empty. Answer will be true only if all characters in second string are *.
if (s1.Length == 0 && s2.Length > 0 && s2[0] == '*')
{
string newS2 = s2.Remove(0, 1);
return CompareString(s1, newS2, true);
}
// One of the strings is empty, and second one is not.
if (s1.Length * s2.Length == 0) return false;
if (wildCard)
{
string newS1 = s1.Remove(0, 1);
if (CompareString(newS1,s2,true) || CompareString(newS1,s2,false))
{
return true;
}
}
else
{
if (s2[0] == '*')
{
string newS2 = s2.Remove(0,1);
if (CompareString(s1,newS2,true) || CompareString(s1,newS2,false))
{
return true;
}
}
else
{
if (s1[0] == s2[0])
{
string newS1 = s1.Remove(0,1);
string newS2 = s2.Remove(0,1);
return CompareString(newS1,newS2,false);
}
else
{
return false;
}
}
}
return false;
}
不需要包含"通配符"标志的辅助方法-您可以用更少的代码来实现。