构造回文字符串(最长公共子序列)----腾讯2017暑期实习生编程题

给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。

输入描述:

输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.



输出描述:

对于每组数据,输出一个整数,代表最少需要删除的字符个数。


输入例子:
abcda
google

输出例子:
2
2

      比较简单的想法就是求原字符串和其反串的最大公共子串的长度,然后用原字符串的长度减去这个最大公共子串的长度就得到了最小编辑长度。(注:最大公共子串并不一定要连续的,只要保证出现次序一致即可看作公共子串)

<span style="font-size:18px;">#include <iostream>
#include <string>
#include <vector>
#include <algorithm>  

using namespace::std ;

/* LCS 算法,求出最长公共子序列的长度 */
int lcs(string str1, string str2) {
	int len1 = str1.size();
	int len2 = str2.size();
	vector<vector<int>> c(len1 + 1, vector<int>(len2 + 1, 0));
	for (int i = 0; i <= len1; i++) {
		for (int j = 0; j <= len2; j++) {
			if (i == 0 || j == 0) {
				c[i][j] = 0;
			}
			else if (str1[i - 1] == str2[j - 1]) {
				c[i][j] = c[i - 1][j - 1] + 1;
			}
			else {
				c[i][j] = c[i - 1][j] > c[i][j - 1] ? c[i - 1][j] : c[i][j - 1];
			}
		}
	}
	int test = str1.size() - str2.size();
	return c[len1][len2];
}

int main() {
    string input ;
    
    while ( cin >> input ) {
        string reverse_input = input;
        reverse(reverse_input.begin(),reverse_input.end());
        int lcs_length = lcs( input, reverse_input ) ;
        int result = input.size() - lcs_length ;
        cout << result << endl ;
    }
    return 0 ;
}</span>


第二次做:

#include <string>
#include <iostream>
#include <algorithm>

using namespace::std ;

int lcs( string str1, string str2 ) {
    int len1  = str1.size() ;
    int len2  = str2.size() ;
    vector<vector<int>> c( len1  + 1, vector<int>( len2 + 1, 0 ) ) ;
    for ( int i = 0; i <= len1 ; ++ i ) {
        for ( int j = 0; j <= len2; ++ j ) {
            if ( i == 0 || j == 0 ) {
                c[i][j] = 0 ;
            } 
            else if ( str1[i -1] == str2[j - 1] ) {
                 c[i][j] = c[i - 1][j - 1] + 1 ;
            } 
            else {
                c[i][j] = c[i - 1][j] > c[i][j - 1] ? c[i - 1][j] : c[i][j - 1] ;
            } 
        }
    }
    return c[len1 ][len2] ;
}

int main() {
    string input ;
    
    while ( cin >> input ) {
        string reverse_input = input ;
        reverse( reverse_input.begin(), reverse_input.end() ) ;
        int lcs_length = lcs( input, reverse_input ) ;
        cout << input.size() - lcs_length << endl ;
    }
    
    return 0 ; 
}

第三次做:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace::std ;

int lcs( string str1, string str2 ) {
    int length1 = str1.size() ;
    int length2 = str2.size() ;
    vector<vector<int>> vec( length1 + 1, vector<int>( length2 + 1, 0 ) ) ;
    for ( int i = 0; i <= length1; ++ i ) {
        for ( int j = 0; j <= length2; ++ j ) {
            if ( i == 0 || j == 0 ) vec[i][j] = 0 ;
            else if ( str1[i - 1] == str2[j - 1] ) vec[i][j] = vec[i - 1][j - 1] + 1 ;
            else vec[i][j] = vec[i - 1][j] > vec[i][j - 1] ? vec[i - 1][j] : vec[i][j - 1] ;
        }
    }
    
    return vec[length1][length2] ;
}

int main() {
    string input ;
    
    while ( cin >> input ) {
        string reverse_input = input ;
        reverse( reverse_input.begin(), reverse_input.end() ) ;
        int lcs_length = lcs( input, reverse_input ) ;
        cout << input.size() - lcs_length << endl ;
    }
    
    return 0 ;
}


第四次做:

#include <iostream>
#include <string>
#include <algorithm>

using namespace::std ;

int main() {
    string input ;
    
    while ( cin >> input ) {
        if ( input.empty() == true ) break ;
        
        string str = input ;
        reverse( str.begin(), str.end() ) ;
        
        vector<vector<int>> vec( input.size() + 1, vector<int>( str.size() + 1, 0 ) ) ;
        for ( int i = 0; i <= input.size(); ++ i ) {
            for ( int j = 0; j <= str.size(); ++ j ) {
                if ( i == 0 || j == 0 ) {
                    vec[i][j] = 0 ;
                } else if ( input[i - 1] == str[j - 1] ) {
                    vec[i][j] = vec[i - 1][j - 1] + 1 ;
                } else {
                    int tmp = max( vec[i - 1][j], vec[i][j - 1] ) ;
                    vec[i][j] = tmp ;
                }
            }
        }
        
        int lcs = vec[input.size()][str.size()] ;
        int result = input.size() - lcs ;
        cout << result << endl ;
    }
    
    return 0 ;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值