64,648
社区成员
发帖
与我相关
我的任务
分享
#include <string>
#include <stdlib.h>
#include <sstream>
#include <iostream>
using namespace std;
#define OPER_ADD_COST 2
#define OPER_ADDR_COST(n) n+2
#define LEN 4
string A[LEN] = { "dsafsadfadf", "aaaaaaaa", "aaaa", "abcdefg" };
string B[LEN] = { "fdfd", "bbbbbbbb", "1aaaa1", "abcdhjk" };
typedef struct
{
string subStr;
string strTrack;
int nABeginPos;
int nAEndPos;
int nBBeginPos;
int nBEndPos;
int nFinalCost;
}tagTransCost;
ostringstream osTrack;
//@Sniper n!
int g_arrTagTransCostIdx = -1;
tagTransCost g_arrTagTransCost[200];
int CalculateCost(bool bContainSub, string A, string B, const string& subStr, tagTransCost& tempTagTransCost)
{
int nMethod1Cost, nMethod2Cost;
if (bContainSub)
{
if (!subStr.empty())
{
string strA = A;
string strB = B;
// have equal subStr.
// Method 1 : remove left and right then add
// remove equal subStr left and right
int nMethod1Cost = 0;
if (tempTagTransCost.nABeginPos == string::npos)
{
strA.erase(subStr.length() - 1);
nMethod1Cost += 2;
osTrack << "Method1 : erase A from " << subStr.length() - 1
<< "to end, A become " << strA
<< ", Method1Cost = " << nMethod1Cost << endl;
}
else if (tempTagTransCost.nABeginPos <= tempTagTransCost.nAEndPos
&& tempTagTransCost.nAEndPos < strA.length())
{
if (tempTagTransCost.nAEndPos < strA.length() - 1)
{
// Right erase
strA.erase(tempTagTransCost.nAEndPos + 1);
nMethod1Cost += 2;
osTrack << "Method1 : erase A from " << tempTagTransCost.nAEndPos + 1
<< " to end, A become " << strA
<< ", Method1Cost = " << nMethod1Cost << endl;
}
if (tempTagTransCost.nABeginPos > 0)
{
// left erase
strA.erase(0, tempTagTransCost.nABeginPos);
nMethod1Cost += 2;
osTrack << "Method1 : erase A from 0 to " << tempTagTransCost.nABeginPos
<< ", A become " << strA
<< ", Method1Cost = " << nMethod1Cost << endl;
}
}
if (subStr.length() != strB.length())
{
if (!strB.substr(0, tempTagTransCost.nBBeginPos).empty())
{
strA.insert(0, strB.substr(0, tempTagTransCost.nBBeginPos));
nMethod1Cost += (strB.substr(0, tempTagTransCost.nBBeginPos)).length();
nMethod1Cost += 2;
osTrack << "Method1 : insert " << strB.substr(0, tempTagTransCost.nBBeginPos)
<< " to A at pos 0 , A become " << strA
<< ", Method1Cost = " << nMethod1Cost << endl;
}
if (!strB.substr(tempTagTransCost.nBEndPos + 1, strB.length()).empty())
{
strA.insert(strA.length(), strB.substr(tempTagTransCost.nBEndPos + 1, strB.length()));
nMethod1Cost += (strB.substr(tempTagTransCost.nBEndPos + 1, strB.length())).length();
nMethod1Cost += 2;
osTrack << "Method1 : insert " << strB.substr(tempTagTransCost.nBEndPos + 1, strB.length())
<< " to A at pos " << strA.length() - (strB.substr(tempTagTransCost.nBEndPos + 1, strB.length())).length() << ", A become " << strA
<< ", Method1Cost = " << nMethod1Cost << endl;
}
}
// Method 2 : clear A[i] and then add new one
int nMethod2Cost = 0;
A.clear();
nMethod2Cost += 2;
osTrack << "Method2 : clear A , Method2Cost = " << nMethod2Cost << endl;
// and then add new chars in B[i]
A = B;
nMethod2Cost += B.length();
nMethod2Cost += 2;
osTrack << "Method2 : copy B to A , Method2Cost = " << nMethod2Cost << endl;
if (nMethod1Cost == 0)
{
tempTagTransCost.nFinalCost = nMethod2Cost;
}
else if (nMethod2Cost == 0)
{
tempTagTransCost.nABeginPos = nMethod1Cost;
}
else
{
tempTagTransCost.nFinalCost =
nMethod1Cost < nMethod2Cost ? nMethod1Cost : nMethod2Cost;
}
}
else
{
// have no equal subStr, so remove all first
A.clear();
tempTagTransCost.nFinalCost += 2;
// and then add new chars in B[i]
A = B;
tempTagTransCost.nFinalCost += B.length();
tempTagTransCost.nFinalCost += 2;
osTrack << "Have no equal subStr, remove all and then copy, FinalCost = " << tempTagTransCost.nFinalCost;
}
}
else
{
// have no equal subStr, so remove all first
A.clear();
tempTagTransCost.nFinalCost += 2;
// and then add new chars in B[i]
A = B;
tempTagTransCost.nFinalCost += B.length();
tempTagTransCost.nFinalCost += 2;
osTrack << "Have no equal subStr, remove all and then copy, FinalCost = " << tempTagTransCost.nFinalCost;
}
return tempTagTransCost.nFinalCost;
}
int FillTransCost(const string& A, const string& B)
{
string shorterStr;
string longerStr;
if (A.length() <= B.length())
{
shorterStr = A;
longerStr = B;
}
else if (A.length() > B.length())
{
shorterStr = B;
longerStr = A;
}
string subStr;
for (int i = shorterStr.length(); i > 0; i--)
{
for (int j = 0; j <= shorterStr.length() - i; j++)
{
subStr = shorterStr.substr(j, i);
{
++g_arrTagTransCostIdx;
memset(&g_arrTagTransCost[g_arrTagTransCostIdx], 0, sizeof(tagTransCost));
g_arrTagTransCost[g_arrTagTransCostIdx].nAEndPos = A.find_last_of(subStr, A.length());
g_arrTagTransCost[g_arrTagTransCostIdx].nABeginPos = g_arrTagTransCost[g_arrTagTransCostIdx].nAEndPos - subStr.length() + 1;
g_arrTagTransCost[g_arrTagTransCostIdx].nBBeginPos = B.find(subStr);
g_arrTagTransCost[g_arrTagTransCostIdx].nBEndPos = g_arrTagTransCost[g_arrTagTransCostIdx].nBBeginPos + subStr.length() - 1;
osTrack << "subStr = " << subStr
<< ", Before CalculateCost A(" << g_arrTagTransCost[g_arrTagTransCostIdx].nABeginPos
<< "~" << g_arrTagTransCost[g_arrTagTransCostIdx].nAEndPos
<< "), B(" << g_arrTagTransCost[g_arrTagTransCostIdx].nBBeginPos
<< "~" << g_arrTagTransCost[g_arrTagTransCostIdx].nBEndPos
<< ")" << endl;
if (string::npos != longerStr.find(subStr))
CalculateCost(true, A, B, subStr, g_arrTagTransCost[g_arrTagTransCostIdx]);
else
CalculateCost(false, A, B, subStr, g_arrTagTransCost[g_arrTagTransCostIdx]);
g_arrTagTransCost[g_arrTagTransCostIdx].strTrack = osTrack.str();
osTrack.str("");
}
subStr.clear();
}
}
return g_arrTagTransCostIdx;
}
int main(int argc, char** argv)
{
int nArrTransCostSize = 0;
for (int i = 0; i < LEN; i++)
{
cout << i <<" : Trans "<< A[i] << " to " << B[i] << " : " << endl;
nArrTransCostSize = FillTransCost(A[i], B[i]);
int nLeastCostIdx = 0;
for (int i = 0; i <= g_arrTagTransCostIdx; ++i)
{
/*cout << "\ncost : " << g_arrTagTransCost[i].nFinalCost << endl
<< "track : "<<endl
<< g_arrTagTransCost[i].strTrack << endl;*/
if (g_arrTagTransCost[nLeastCostIdx].nFinalCost > g_arrTagTransCost[i].nFinalCost)
{
nLeastCostIdx = i;
}
}
cout << "Final Least Cost = " << g_arrTagTransCost[nLeastCostIdx].nFinalCost << "\n"
<< "Track : \n"
<< g_arrTagTransCost[nLeastCostIdx].strTrack << "\n" << endl;
g_arrTagTransCostIdx = -1;
}
return 0;
}
int func1 (const char a[] ,const char b[] ,int i ,int ir ,int j ,int jr) {
//ab有相同前缀,则去除掉也不影响
while (i <= ir && j <= jr && a[i] == b[j]) {
i++ ;
j++ ;
}
//ab有相同后缀,则去除掉也不影响
while (i <= ir && j <= jr && a[ir] == b[jr]) {
ir-- ;
jr-- ;
}
if (i > ir) {
//如果a是空串,则只需增加操作,代价是b的长度+2
return (jr + 1 - j) + 2 ;
} else if (j > jr) {
//如果b是空串,则只需删除操作,代价是2
return 2 ;
}
//如果ab无公共前缀,则代价是a的所有前后子串转为b的最小值
//最坏是a的空子串
int tmp = 2 + (jr + 1 - j) + 2 ;
//a的非空后子串
for (int k = i + 1 ; k <= ir ; k++)
tmp = min (tmp ,2 + func1 (a ,b ,k ,ir ,j ,jr)) ;
//a的非空前子串
for (int k = ir - 1 ; k >= i ; k--)
tmp = min (tmp ,2 + func1 (a ,b ,i ,k ,j ,jr)) ;
return tmp ;
}
//递归法
int func1 (const string &a ,const string &b) {
return func1 (&a[0] ,&b[0] ,0 ,(int) a.length () - 1 ,0 ,(int) b.length () - 1) ;
}
//动态规划
int func2 (const string &a ,const string &b) {
const int la = (int) a.length () ;
const int lb = (int) b.length () ;
vector<int> ret (la * la * lb * lb) ;
#define VRET(a ,b ,c ,d) (ret[(a) * la * lb * lb + (b) * lb * lb + (c) * lb + (d)])
for (int ix = la - 1 ; ix >= 0 ; ix--)
for (int irx = 0 ; irx < la ; irx++)
for (int jx = lb - 1 ; jx >= 0 ; jx--)
for (int jrx = 0 ; jrx < lb ; jrx++) {
int i = ix ;
int ir = irx ;
int j = jx ;
int jr = jrx ;
while (i <= ir && j <= jr && a[i] == b[j]) {
i++ ;
j++ ;
}
while (i <= ir && j <= jr && a[ir] == b[jr]) {
ir-- ;
jr-- ;
}
if (i > ir) {
VRET (ix ,irx ,jx ,jrx) = (jr + 1 - j) + 2 ;
continue ;
} else if (j > jr) {
VRET (ix ,irx ,jx ,jrx) = 2 ;
continue ;
}
int tmp = 2 + (jr + 1 - j) + 2 ;
for (int k = i + 1 ; k <= ir ; k++) {
const auto r0x = ret[k * la * lb * lb + ir * lb * lb + j * lb + jr] ;
tmp = min (tmp ,2 + VRET (k ,ir ,j ,jr)) ;
}
for (int k = ir - 1 ; k >= i ; k--) {
const auto r0x = ret[i * la * lb * lb + k * lb * lb + j * lb + jr] ;
tmp = min (tmp ,2 + VRET (i ,k ,j ,jr)) ;
}
VRET (ix ,irx ,jx ,jrx) = tmp ;
continue ;
}
return VRET (0 ,la - 1 ,0 ,lb - 1) ;
#undef VRET
}