将最长的公共子序列减少到最长的子序列

时间:2016-01-07 13:11:18

标签: algorithm dynamic-programming

如果最多一个序列有重复,我们可以将最长公共子序列问题减少到最长增加子序列问题。 {(3}}:

解释了减少问题的过程
  

假设你有序列:

javafx.fxml.LoadException: 
/home/mert/workspace/AddressApp/bin/AddressAppView/PersonOverview.fxml:25

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
    at AddressAppController.MainApp.showPersonOverview(MainApp.java:77)
    at AddressAppController.MainApp.start(MainApp.java:47)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication.lambda$null$49(GtkApplication.java:139)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: Can not set AddressAppController.MainApp field AddressAppView.PersonOverviewController.mainApp to javafx.scene.layout.AnchorPane
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
    at java.lang.reflect.Field.set(Field.java:764)
    at javafx.fxml.FXMLLoader.injectFields(FXMLLoader.java:1163)
    at javafx.fxml.FXMLLoader.access$1600(FXMLLoader.java:103)
    at javafx.fxml.FXMLLoader$ValueElement.processValue(FXMLLoader.java:857)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:751)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
    ... 13 more
     

然后,创建一个整数序列S3,您必须将S2中每个元素的位置放在S1中(如果该元素在S1中不存在,则忽略该元素)。在示例中:

S1 = {D, B, A, C, E}
S2 = {E, Z, X, D, A, Y, C}
     

然后,在S3中找到LIS。要查找原始元素,只需使用LIS中的整数作为S1的索引。例如,在这种情况下,S3的LIS为S3 = {4, 0, 2, 3} // Z, X and Y in S2 where ignored ,其中代表序列{0, 2, 3}

这种方法有何用处?为什么这种减少解决了找到最长公共子序列的问题?

1 个答案:

答案 0 :(得分:2)

鉴于你如何构建S3,你可以保证S3的元素只指向"只有#34; S1和S2的共同要素。

通过使用位置并找到最长的增加子序列,您可以确保您找到的内容将是原始S1和S2的子序列,而不仅仅是它们共有的元素数量:< / p>

  • 它将是S1的子序列,因为S3中元素的数值编码S1中的位置,因此增加 S3的子序列= S1的子序列
  • 它将是S2的子序列,因为在S3的元素中编码的元素与S2的元素的顺序相同,因此S3的子序列 = S2的子序列

因此,S3的最长增长子序列将&#34;编码&#34;:

  • S1的后续序列
  • S2
  • 的后续序列
  • 仅包含S1和S2中存在的元素的序列
  • 这种子序列中最长的

即。 S1和S2之间最长的共同子序列

你可以&#34;解码&#34;通过使用所描述的过程,即采用S1的元素,索引=元素S3。

注意:正如链接中所指出的,这只适用于最多其中一个序列有重复的情况,并且在构建S3时,您应该将序列视为S1而不重复。

这似乎与更常见的reduction of LIS to LCS相反。