Пусть N - длина заданной строки и R - количество правил.
Расширение дерева сверху вниз дает вычислительную сложность O (NR^N) в худшем случае (строка ввода типа aaa...
и правила aa -> a
).
Доказательство:
Корень дерева имеет (N-1) R детей, которые имеют (N-1) R^2 детей, ..., которые имеют (N-1) R^N детей (листья).Таким образом, общая сложность представляет собой O ((N-1) R + (N-1) R^2 + ... (N-1) R^N) = O (N (1 + R 2+ ... + R^N)) = (с использованием binomial theorem) = O (N (R + 1)^N) = O (NR^N).
Рекурсивного Java реализация этого наивного подхода:
public static void main(String[] args) {
Map<String, Character[]> rules = new HashMap<String, Character[]>() {{
put("ab", new Character[]{'b', 'c'});
put("ba", new Character[]{'a'});
put("cc", new Character[]{'b'});
}};
System.out.println(simplify("abab", rules));
}
public static Set<String> simplify(String in, Map<String, Character[]> rules) {
Set<String> result = new HashSet<String>();
simplify(in, rules, result);
return result;
}
private static void simplify(String in, Map<String, Character[]> rules, Set<String> result) {
if (in.length() == 1) {
result.add(in);
}
for (int i = 0; i < in.length() - 1; i++) {
String two = in.substring(i, i + 2);
Character[] rep = rules.get(two);
if (rep != null) {
for (Character c : rep) {
simplify(in.substring(0, i) + c + in.substring(i + 2, in.length()), rules, result);
}
}
}
}
Bas Swinckels's O (RN 3 ^) реализация Java (с HashMap
в качестве кэша запоминания):
public static Set<String> simplify2(final String in, Map<String, Character[]> rules) {
Map<String, Set<String>> cache = new HashMap<String, Set<String>>();
return simplify2(in, rules, cache);
}
private static Set<String> simplify2(final String in, Map<String, Character[]> rules, Map<String, Set<String>> cache) {
final Set<String> cached = cache.get(in);
if (cached != null) {
return cached;
}
Set<String> ret = new HashSet<String>();
if (in.length() == 1) {
ret.add(in);
return ret;
}
for (int i = 1; i < in.length(); i++) {
String head = in.substring(0, i);
String tail = in.substring(i, in.length());
for (String c1 : simplify2(head, rules)) {
for (String c2 : simplify2(tail, rules, cache)) {
Character[] rep = rules.get(c1 + c2);
if (rep != null) {
for (Character c : rep) {
ret.add(c.toString());
}
}
}
}
}
cache.put(in, ret);
return ret;
}
Выход в обоих подходах:
[b, c]
Правило всегда имеет от 2 до 1 карт? Каково ваше лучшее решение? кратчайшая строка? строка с теми же буквами? – cerkiewny
Вам нужно показать нам немного усилий. Вы рассмотрели, как вы подходите к этой проблеме? Дайте нам свои мысли. * Попробуйте что-нибудь. * Когда вы застряли, сообщите нам, что вы пробовали, и объясните, в чем проблема. –
И что вы имеете в виду с [DP] (http://www.acronymfinder.com/Information-Technology/DP.html)? –