使用记忆的最长公共子序列

时间:2018-12-29 19:15:31

标签: c++ dynamic-programming memoization

该程序具有使用记忆的最长公共子序列。但是下面的示例给出的答案为0。在添加备忘录之前,它给出了正确的答案2。

我认为我在添加备注方面确实犯了错误。谁能帮我解决这段代码有什么问题吗?

#include<bits/stdc++.h>
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
 char a[100]="bd",b[100]="abcd";
 int lcs1[100][100];

 int lcs(int i,int j){
     int temp;
     if(lcs1[i][j]!=-1)

     if(a[i]=='\0'||b[i]=='\0'){
        return 0;
     }
     if(lcs1[i][j]!=-1)
        return lcs1[i][j];
     else if (a[i]==b[j])
        temp = 1+lcs(i+1,j+1);
     else
        temp = max(lcs(i+1,j),lcs(i,j+1));
     lcs1[i][j] = temp;
     return temp;

 }
 int main(){

     int temp = lcs(0,0);
     memset(lcs1,-1,sizeof(lcs1));
     printf("%d",temp);

 }

2 个答案:

答案 0 :(得分:1)

2个问题:

  • 您正在调用lcs()
  • 后初始化备忘录数组
  • if的开头有一个额外的lcs()

以下是更正的代码:

#include<cstring>
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
 char a[100]="bd",b[100]="abcd";
 int lcs1[100][100];

 int lcs(int i,int j){
     int temp;
     //if(lcs1[i][j]!=-1)       // problem 2

     if(a[i]=='\0'||b[i]=='\0'){
        return 0;
     }
     if(lcs1[i][j]!=-1)
        return lcs1[i][j];
     else if (a[i]==b[j])
        temp = 1+lcs(i+1,j+1);
     else
        temp = max(lcs(i+1,j),lcs(i,j+1));
     lcs1[i][j] = temp;
     return temp;

 }
 int main(){
     memset(lcs1,-1,sizeof(lcs1));  // problem 1
     int temp = lcs(0,0);
     printf("%d",temp);

 }

注意:避免全局变量是一种好习惯。尝试将它们封装在结构或类中。有关正确的C ++实现,请参见@Matthieu Brucher的答案。

答案 1 :(得分:1)

只是为了好玩,一个带有类的C ++ 17实现:

public void onButtonNextActivityClick(View v){
    Intent intent = new Intent(MainActivity.this,SecondActivity.class);
    startActivity(intent);
}

还要注意,通常的问题不仅是返回计数,还包括字符串本身。