使用TensorFlow Object Detection Api 進行環境搭建、訓練自定義的資料集、輸出模型、Android端使用模型目標檢測
阿新 • • 發佈:2020-12-14
題目要求:
給定兩個序列X和Y,基於備忘錄方法,編寫程式找出X和Y所有的最長公共子序列
主要思路:
本題的主要思路是先輸入兩個公共序列,然後採用備忘錄方法來找出最長公共子序列的長度,根據最長公共子序列的長度來找出那些公共元素,把它們存到一個數組當中再輸出,這樣就可以解決問題了。
備忘錄方法,即採用自頂向下的遞迴來解決問題:從目標開始,將問題劃分,對子問題求解,直到邊界。第一步是先對備忘錄進行初始化,為了之後快速判斷是否有已經填寫過備忘錄。然後從兩個序列的最後一個數開始,如果這兩個數相等,就去查詢它們對應的備忘錄,如果大於-1說明已經計算過,就直接輸出結果,否則要查詢這兩個數的前一個數對應的備忘錄,因為這個備忘錄是由斜上方的備忘錄加一得到的,這樣一直查詢到邊界為止;如果這兩個最後的數不相等,那麼對應的備忘錄則是由它的左邊和上方的備忘錄求最大值得到的,需要對這兩個備忘錄進行查詢,如果都大於-1,說明已經計算過,就直接輸出結果,否則要遞迴呼叫函式進行計算。這樣就能得到兩個序列的最長公共子序列的長度了。
該演算法的時間複雜度O(m * n),m,n為字串的長度。
#include <iostream>
#include <string>
#define Max 50
using namespace std; //最長公共子字串,遞迴的備忘錄寫法
int cc[Max][Max];
int max(int x, int y)
{
if (x > y)
{
return x;
}
else
{
return y;
}
}
int LCS_L(string s3,string s4,int len3,int len4, int cc[50][50])
{
/* cout<<s3<<" "<<s4<<" "<<len3<<" "<<len4<<" "<<endl;
for(int s=0;s<len3;s++)
{
for(int t=0;t<len4;t++)
{
cout<<cc[s][t]<<'\t';
}
cout<<'\n';
}*/
if (cc[len3][len4]>-1) //如果cc[len3][len4]>-1,說明不是初值,已經計算過了,直接返回備忘錄裡面的值
{
return cc[len3][len4];
}
// 否則將數值存進備忘錄裡面
if (len3==0||len4==0)
{
cc[len3][len4]=0;
}
else if(s3[len3]==s4[len4])//如果s3[len3]==s4[len4],此時cc[len3][len4]=cc[len3-1][len4-1]+1
{
if(cc[len3-1][len4-1]>-1)//此時cc[len3-1][len4-1]已經計算過了
cc[len3][len4]=cc[len3-1][len4-1]+1;
else
cc[len3][len4]=LCS_L(s3,s4,len3-1,len4-1,cc)+1;//否則要重新呼叫函式計算
}
else //如果s3[len3]!=s4[len4],cc[len3][len4]=max(cc[len3-1][len4],cc[len3][len4-1])
{
if(cc[len3-1][len4]>-1&&cc[len3][len4-1]>-1)//此時cc[len3-1][len4],cc[len3][len4-1]已經計算過了
cc[len3][len4]=max(cc[len3-1][len4],cc[len3][len4-1]);
else
cc[len3][len4]=max(LCS_L(s3,s4,len3-1,len4,cc),LCS_L(s3,s4,len3,len4-1,cc));//否則要重新呼叫函式計算
}
return cc[len3][len4];
}
void LCS_Print(string s3,int len3,int len4, int cc[50][50])//列印最長公共子序列
{
int LCS_length=cc[len3][len4];
char lcs_print[50]=" ";//這個陣列儲存要列印的字串
while(LCS_length>0)
{
if(cc[len3][len4]!=cc[len3-1][len4-1])
{
if(cc[len3-1][len4]==cc[len3][len4-1])
{
lcs_print[LCS_length-1]=s3[len3-1];//這個數是從斜上方加1得到的 ,並且儲存的時候從後往前儲存
len3--;len4--;
LCS_length--;
}
else if(cc[len3-1][len4]>cc[len3][len4-1]) len3--;//從左邊得到的數
else len4--;//從右邊得到的數
}
else
{
len3--;len4--;
}
}
cout<<"這個最長的公共子序列是:";
cout<<lcs_print<<" "<<endl;
}
void main()
{
string s3,s4;
cout<<"請輸入兩個序列,以空格鍵隔開:"<<'\n';
cin>>s3>>s4;
int len3 = s3.length();
int len4 = s4.length();
for(int i=1;i<=len3;i++)//將陣列cc初始化
{
for(int j=1;j<=len4;j++)
{
cc[0][0]=0;
cc[i][0]=0;
cc[0][j]=0;
cc[i][j]=-1;
}
}
cout<<"兩個序列的公共最長子序列的長度為:"<<LCS_L(s3,s4,len3,len4,cc)<<'\n';
LCS_Print(s3,len3,len4,cc);
}