概述
1、求两个集合的最大公共连续子集
2、求指定子集和的子集
思路
1、求两个集合的最大公共连续子集
使用回溯法
2、求指定子集和的子集
使用动态规划法
源码
本文主要是以C、C++、QT为基础进行编程,运行前简单修改即可。测试入口函数为 void Test_MaxSubset()。
#include "QTime"
#include "QList"
static const quint32 SET1_ACOUNT = 100;//集合1的数量
static const quint32 SET1_VALUE_MAX = 9;
static quint32 gSet1[SET1_ACOUNT];
static const quint32 SET2_ACOUNT = 60;//集合2的数量
static const quint32 SET2_VALUE_MAX = 9;
static quint32 gSet2[SET2_ACOUNT];
static QList<quint32> gList;
void MaxSubset_OutputSet()
{
quint32 loop = 0;
printf("\nSet1:");
while(loop<SET1_ACOUNT)
{
printf("%d ",gSet1[loop]);
loop++;
}
printf("\nSet2:");
loop = 0;
while(loop<SET2_ACOUNT)
{
printf("%d ",gSet2[loop]);
loop++;
}
printf("\n");
}
void MaxSubset_OutputSet1(quint32 outIndex, quint32 outLen)
{
quint32 loop = outIndex;
printf("\nSet1: Index=%d, Len=%d\n", outIndex, outLen);
while(loop<SET1_ACOUNT && loop<(outLen+outIndex))
{
printf("%d ",gSet1[loop]);
loop++;
}
printf("\n");
}
void MaxSubset_OutputSet2(quint32 outIndex, quint32 outLen)
{
quint32 loop = outIndex;
printf("\nSet2: Index=%d, Len=%d\n", outIndex, outLen);
while(loop<SET2_ACOUNT && loop<(outLen+outIndex))
{
printf("%d ",gSet2[loop]);
loop++;
}
printf("\n");
}
void MaxSubset_InitSet()
{
quint32 loop = 0;
QTime time = QTime::currentTime();
qsrand(time.msec());
while(loop<SET1_ACOUNT)
{
gSet1[loop] = qrand()%SET1_VALUE_MAX +1;
loop++;
}
loop = 0;
while(loop<SET2_ACOUNT)
{
gSet2[loop] = qrand()%SET2_VALUE_MAX +1;
loop++;
}
}
/*
note:获取两个集合的最大公共(连续)子集
return:子集长度
*/
quint32 MaxSubset_GetMaxSameContinuousSubset()
{
quint32 i,j,tempLen;
quint32 index1=0,index2=0,maxLen=0;
for(i=0;i<SET1_ACOUNT;i++)
{
for(j=0;j<SET2_ACOUNT;j++)
{
tempLen = 0;
while((i+tempLen)< SET1_ACOUNT
&& (j+tempLen)< SET2_ACOUNT
&& gSet1[i+tempLen] == gSet2[j+tempLen])
{
tempLen++;
}
if(tempLen > maxLen)
{
maxLen = tempLen;
index1 = i;
index2 = j;
}
}
}
if(maxLen != 0)
{
MaxSubset_OutputSet1(index1, maxLen);
MaxSubset_OutputSet2(index2, maxLen);
}
return maxLen;
}
/*
* 获取集合1的子集,限制条件:子集和为 sum
* 类似背包问题
*/
quint32 MaxSubset_Set1SubsetSum_GetSum(quint32 endIndex, quint32 targetSum)
{
quint32 s1=0,s2=0;
if(endIndex>=SET1_ACOUNT || 0==targetSum)
{
return 0;
}
//qDebug()<<"endIndex:"<<endIndex<<"targetSum:"<<targetSum;
if(targetSum >= gSet1[endIndex])
{
s1 = gSet1[endIndex];
if(endIndex > 0)
{
s1 += MaxSubset_Set1SubsetSum_GetSum(
endIndex-1, targetSum-gSet1[endIndex]);
}
}
if(s1 == targetSum)
{
return s1;
}
if(endIndex > 0)
{
s2 = MaxSubset_Set1SubsetSum_GetSum(endIndex-1, targetSum);
}
if(s2 == targetSum)
{
return s2;
}
return 0;
}
bool MaxSubset_Set1SubsetSum_GetItem(quint32 Set1acount, quint32 targetSum)
{
qint32 i=Set1acount-1;
quint32 s;
bool ok=false;
while(i>=0)
{
if(0 == targetSum)
{
break;
}
if(targetSum < gSet1[i])
{
i--;
continue;
}
s = gSet1[i] +
MaxSubset_Set1SubsetSum_GetSum(i-1, targetSum-gSet1[i]);
if(s == targetSum)
{
qDebug()<<"["<<i<<"]="<<gSet1[i];
targetSum -= gSet1[i];
ok = true;
}
i--;
}
return ok;
}
void Test_MaxSubset()
{
MaxSubset_InitSet();
MaxSubset_OutputSet();
qDebug()<<"MaxSubset_GetMaxSameContinuousSubset:";
MaxSubset_GetMaxSameContinuousSubset();
qDebug()<<"MaxSubset_Set1SubsetSum_GetItem:";
if(MaxSubset_Set1SubsetSum_GetItem(SET1_ACOUNT, 30))
{
qDebug()<<"MaxSubset_Set1SubsetSum_GetItem Succ";
}
}
运行结果
略