我无法弄清楚如何解决这个问题:
给出两个字符串,一个表示模式,一个是随机字符串,确定它是否与第一个字符串匹配
前:
string1: "aaba"
string2: "catcatdogcat"
因此,string1和string2是模式匹配的
如果string2是"catcatcatcat"
,则不会进行模式匹配。
对任何模式和字符串执行此操作。
我知道这是递归,但我很坚持......如何解决这个问题
答案 0 :(得分:2)
好的,我会尝试解释这个递归,听起来没错,但我没有机会测试它(不在家里)。
采用向量v ['字母大小'],其中v [i] = string2中的字母数=字符串1中的字母i。
在你的情况下,最终是:v ['a'] = 3,v [b] = 3;
使用1初始化矢量。
对于rec函数:
你从string1获取第一个字母:a; 表示来自string2的字符串是从string2开始并以string2 + v ['a']结束的字符串;这是'c'; 你现在检查这是否是一个有效的解决方案,它是。
然后你进入rec(string1 + 1),再写一次, 因为v ['a']仍然= 1然后你把第二个a as ='a'。 你检查这是否是一个有效的解决方案,并不是因为你已经将第一个a定义为'c'。 你回到递归中并递增v ['a'],从乞讨开始。
你接受string1的第一个字母:a; 从string2代表'ca',(现在v ['a'] = 2) 检查是否有效。 rec(string1 +1);
依旧...... 在某一点上你会达到v ['a'] = 3而v ['b'] = 3; 然后使用rec功能,您将找到解决方案。
我发现在一个交互式函数中更容易实现,但你说了一些关于递归的事情,所以是的。
答案 1 :(得分:2)
获取唯一字母的数量。然后,您希望使用以下约束迭代每个字母的所有可能长度组合:
即,对于2个唯一字母和字符串长度为4,可能的长度为:
(1,3)和(2,2)
从这里开始很简单。对于每个唯一的字母,您可以找到该字母必须代表给定字符串的字符串,因为您知道每个字母的长度。然后将每个字母映射到它必须表示的字符串,如果在任何时候字母对应于与之前的实例不匹配的字符串,那么就没有匹配。
对于你的例子:
string1: "aaba"
string2: "catcatdogcat"
这里,对于长度为(3,3)的迭代。因为我们知道a的长度为3,所以我们知道a的第一次迭代必须是“cat”。然后下一个a,对应于“cat”(仍有匹配)。然后接下来的3个必须对应b。这是第一个b,所以它可以匹配任何3个字符。然后再将最后一个匹配给猫,你就完成了。
如果您希望a,b,c在@MartijnCourteaux评论中有所独特(现在您的问题我再次阅读),那么最后您可以检查地图中是否有常见值,如果有的话常见的价值就是你没有匹配。
如果在任何迭代中都匹配,则字符串与模式匹配。如果在所有迭代中没有匹配,则只有没有匹配。
答案 2 :(得分:1)
这很容易实现:
正则表达式是要走的路。在Regex中,有一种称为反向引用的东西。反向引用需要以匹配相同的字符串,提到的匹配组已经匹配。即正则表达式^([ab])\\1$
将匹配aa
或bb
等每个字符串。第一组匹配a或b - 但反向引用NEEDS匹配相同的东西,匹配组(在本例中为“1”)匹配。
因此,您需要做的就是:将基于字符串的模式转换为正则表达式模式。
示例:
String regex = "^([a-z]+)\\1([a-z]+)\\1$";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher("catcatdogcat");
if (m.matches()){
System.out.println("matches!");
System.out.println(m.group(0));
System.out.println(m.group(1));
System.out.println(m.group(2));
}else{
System.out.println("no matches!");
}
产生
matches!
catcatdogcat
cat
dog
这将完全匹配您的给定字符串“catcatdogcat”,而匹配组1为“cat”并匹配组2为“dog”。
您现在需要做的是:
aaba
char。([a-z]+)
并记下该匹配组的编号(数组,Hashmap,...)\\1
(如果该信件的记录号码为1)^
和$
最后,您的字符串aaba
将转换为^([a-z]+)\\1([a-z]+)\\1$
并满足您的需求。模式abccba
将成为正则表达式^([a-z]+)([a-z]+)([a-z]+)\\3\\2\\1$
最后使用匹配器检查给定的字符串。
此示例仅假定小写字符,但您可以对其进行扩展。
然而保持“+”是很重要的,因为“*”将允许零长度匹配,这将使你的正则表达式匹配所有时间。
提到的第二个例子:
import java.util.regex.*;
public class HelloWorld {
public static void main(String[] args) {
String regex = "^([a-z]+)([a-z]+)([a-z]+)\\3\\2\\1$";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher("catdogcowcowdogcat");
if (m.matches()){
System.out.println("matches!");
System.out.println(m.group(0));
System.out.println(m.group(1));
System.out.println(m.group(2));
System.out.println(m.group(3));
}else{
System.out.println("no matches!");
}
}
}
产生
matches!
catdogcowcowdogcat
cat
dog
cow
编辑:如果需要(即使它不符合您的要求 - 请参阅评论):
public static String convertToRegex(String pattern){
String regex = "";
Map<Character, Integer> refs = new HashMap<Character, Integer>();
Integer i=1;
for (Character c : pattern.toCharArray()){
if (refs.containsKey(c)){
//known.
regex += "\\" + refs.get(c);
}else{
//unknown
regex += "([a-z]+)";
refs.put(c, i++);
}
}
return "^" + regex + "$";
}