根据以下规则将文本拆分为子字符串:
我不知道如何解决这个问题,我猜它与"动态编程"有关.任何人都可以帮我用C#或Java实现它吗?非常感谢.
Bol*_*olo 11
一种贪婪的方法是要走的路:
这是一个reductio-ad-absurdum证明,以上产生了最佳解决方案.假设有比贪婪分裂更好的分裂.让我们跳到两个分裂开始不同的点,并在此之前删除所有内容.
情况1)前N个字符中的一个数字.
假设有一个输入,其中切掉前N个字符不能产生最佳解决方案.
Greedy split: |--N--|...
A better split: |---|--...
^
+---- this segment can be shortened from the left side
Run Code Online (Sandbox Code Playgroud)
但是,推定的更好的解决方案的第二部分可以始终从左侧缩短,第一部分扩展到N个字符,而不改变段的数量.因此,矛盾:这种分裂并不比贪婪的分裂更好.
情况2)第一个K(N <K <= M)字符中没有数字.
假设存在一个输入,其中切掉前K个字符不能产生最佳解.
Greedy split: |--K--|...
A better split: |---|--...
^
+---- this segment can be shortened from the left side
Run Code Online (Sandbox Code Playgroud)
同样,"更好"的分裂可以在不改变分段数量的情况下转换为贪婪分裂,这与最初的假设相矛盾,即最初的假设比贪婪的分裂更好.
因此,贪婪的分裂是最佳的.QED
import sys
m, n, text = int(sys.argv[1]), int(sys.argv[2]), sys.argv[3]
textLen, isDigit = len(text), [c in '0123456789' for c in text]
chunks, i, j = [], 0, 0
while j < textLen:
i, j = j, min(textLen, j + n)
if not any(isDigit[i:j]):
while j < textLen and j - i < m and not isDigit[j]:
j += 1
chunks += [text[i:j]]
print chunks
Run Code Online (Sandbox Code Playgroud)
public class SO {
public List<String> go(int m, int n, String text) {
if (text == null)
return Collections.emptyList();
List<String> chunks = new ArrayList<String>();
int i = 0;
int j = 0;
while (j < text.length()) {
i = j;
j = Math.min(text.length(), j + n);
boolean ok = true;
for (int k = i; k < j; k++)
if (Character.isDigit(text.charAt(k))) {
ok = false;
break;
}
if (ok)
while (j < text.length() && j - i < m && !Character.isDigit(text.charAt(j)))
j++;
chunks.add(text.substring(i, j));
}
return chunks;
}
@Test
public void testIt() {
Assert.assertEquals(
Arrays.asList("asdas", "d332", "4asd", "fsdxf", "23"),
go(5, 4, "asdasd3324asdfsdxf23"));
}
}
Run Code Online (Sandbox Code Playgroud)