Fibonacci单词定义与Fibonacci数的定义类似:
FIB(1)=b,FIB(2)=a,FIB(k+2)=FIB(k+1)*FIB(k)(k>=1),*的意思是两个字符串连接,所以FIB3=ab;FIB4=aba;FIB5=abaab;
现在给出一个长度最多为30的模式串,仅含字母a或b.
计算第n个Fib单词中含有多少个这样的模式串.模式串在Fib单词中的位置可以重叠.
Input
该题有多组测试数据,每组测试数据2行,第一行是单词.第二行是n,n<=200.
Output
模式串出现的次数.
Sample Input
aba
6
Sample Output
3
对于n>12所有的都可以拆成 n =11和 n= 12 的和
设n = 11的字符串 用 b 代替, n = 12 的用 a 代替则n = 21 n = 22 和 n = 11 ,n = 12 是相同的字符串,只要处理字符串首尾连接处产生的模式匹配即可,好多重复代码可以用函数表示。基本功能实现了。速度也没什么问题。超大数字只简单用了个 256的数组.好像开大了,128就够了
如果对于n=11,n=12 以及他们首尾连接的4种情况,字符串匹配个数为0,那么对于任何n>12匹配个数都为0,下面程序没有对此优化
int cmp(const string& s1,const string& s2)
{
int count=0;
s1.find(s2);
string::size_type fd = s1.find(s2);
while(fd != string::npos)
{
++count;
++fd;
fd = s1.find(s2,fd);
}
return count;
}
//超长数字加 n
void bignum(char* num,int n,int len)
{
int m=0;
for(int i=255;i>0;i--)
{
m = n - n/10*10;
num[i] += m;
if(num[i]>=10)
{
int j = i;
while(num[j]>=10)
{
if(j>len)
{
cout<<"越界"<<endl;
break;
}
num[j--] -= 10;
num[j] += 1;
}
}
n /= 10;
if(n==0)
{
break;
}
}
}
//可以使用128位数组,提高效率
//超长数字相加
void bignum(char* num,char* str,int len)
{
for(int i=255;i>0;i--)
{
num[i] += str[i];
int j = i;
while(num[j]>=10)
{
num[j--] -= 10;
num[j] += 1;
}
}
}
void fib1(string str,int n)
{
string f1="b";
string f2="a";
string f3;
char count[256] = {0};
string f;
string ay;
string a1= "b";
string a2= "a";
char ct[2][256] ={0};
int cc[4] = {0};
char ct1[256],ct2[256];
if(n==0)
f3=f1;
if(n==1)
f3=f2;
int i = 0;
int v = n / 10;
int x = n % 10;
if(v > 0)
{
for(i=2;i<12;i++)
{
f3 = f2 + f1;
f1=f2;
f2 = f3;
}
bignum(ct[1],cmp(f2,str),256);
bignum(ct[0],cmp(f1,str),256);
}
else
{
for(i=2;i<n;i++)
{
f3 = f2 + f1;
f1=f2;
f2 = f3;
}
int tt = cmp(f2,str);
cout<<tt<<endl;
return;
}
string::size_type len2 = f2.length();
string::size_type len1 = f1.length();
string::size_type len = str.length();
for(int i=1;i<v;i++)
{
int flag = 0;
string tmp,tmp1,tmp2,tmp3,tmp4;
const char * sa = f2.c_str();
for(int j=i;j>1;j--)
{
if(flag == 2 || flag == 0)
{
if(sa[len2] == 'b')
{
flag = 1;
sa = f1.c_str();
}
}
else
{
if(sa[len1] == 'a')
{
flag = 2;
sa = f2.c_str();
}
}
}
if(flag == 2 || flag == 0)
{
tmp2 = f2.substr(len2-len+1,len2);
}
else
{
tmp2 = f1.substr(len1-len+1,len1);
}
sa = f2.c_str();
flag = 0;
for(int j=i;j>1;j--)
{
if(sa[0] == 'a')
{
sa = f2.c_str();
flag = 2;
}
else
{
sa = f1.c_str();
flag = 1;
}
}
if(flag == 2 || flag == 0)
{
tmp1 = f2.substr(0,len-1);
}
else
{
tmp1 = f1.substr(0,len-1);
}
tmp = tmp2 + tmp1;
cc[3] = cmp(tmp,str);
sa = f1.c_str();
for(int j=i;j>1;j--)
{
if(sa[0] == 'a')
{
sa = f2.c_str();
flag = 2;
}
else
{
sa = f1.c_str();
flag = 1;
}
}
if(flag == 1 || flag == 0)
{
tmp4 = f1.substr(0,len-1);
}
else
{
tmp4 = f2.substr(0,len-1);
}
tmp = tmp2 + tmp4;
cc[2] = cmp(tmp,str); //ab连接
sa = f1.c_str();
flag = 0;
for(int j=i;j>1;j--)
{
if(flag == 1 || flag == 0)
{
if(sa[len1] == 'b')
{
flag = 1;
sa = f1.c_str();
}
}
else
{
if(sa[len2] == 'a')
{
flag = 2;
sa = f2.c_str();
}
}
}
if(flag == 1 || flag == 0)
{
tmp3 = f1.substr(len1-len+1,len1);
}
else
{
tmp3 = f2.substr(len2-len+1,len2);
}
tmp = tmp3 + tmp1; //ba
cc[1] = cmp(tmp,str);
tmp = tmp3 + tmp4; //bb
cc[0] = cmp(tmp,str);
sa = f1.c_str();
memset(count,0,256*sizeof(char));
while(sa)
{
if(*sa == 'a')
{
bignum(count,ct[1],256);
}
else
{
bignum(count,ct[0],256);
}
if(!sa[1])
{
memcpy(ct1,count,256);
break;
}
if(sa[1] == 'a' && *sa == 'a')
{
bignum(count,cc[3],256);
}
if(sa[1] == 'a' && *sa == 'b')
{
bignum(count,cc[1],256);
}
if(sa[1] == 'b' && *sa == 'a')
{
bignum(count,cc[2],256);
}
if(sa[1] == 'b' && *sa == 'b')
{
bignum(count,cc[0],256);
}
sa++;
}
sa = f2.c_str();
memset(count,0,256*sizeof(char));
while(sa)
{
if(*sa == 'a')
{
bignum(count,ct[1],256);
}
else
{
bignum(count,ct[0],256);
}
if(!sa[1])
{
memcpy(ct2,count,256);
break;
}
if(sa[1] == 'a' && *sa == 'a')
{
bignum(count,cc[3],256);
}
if(sa[1] == 'a' && *sa == 'b')
{
bignum(count,cc[1],256);
}
if(sa[1] == 'b' && *sa == 'a')
{
bignum(count,cc[2],256);
}
if(sa[1] == 'b' && *sa == 'b')
{
bignum(count,cc[0],256);
}
sa++;
}
memcpy(ct[1],ct2,256);
memcpy(ct[0],ct1,256);
}
if( x-2 > 0)
{
memset(count,0,256*sizeof(char));
for(int i=2;i<x;i++)
{
ay = a2+a1;
a1 = a2;
a2 = ay;
}
int flag = 0;
string tmp,tmp1,tmp2,tmp3,tmp4;
const char * sa = f2.c_str();
for(int j=v-1;j>1;j--)
{
if(flag == 2 || flag == 0)
{
if(sa[len2] == 'b')
{
flag = 1;
sa = f1.c_str();
}
}
else
{
if(sa[len1] == 'a')
{
flag = 2;
sa = f2.c_str();
}
}
}
if(flag == 2 || flag == 0)
{
tmp2 = f2.substr(len2-len+1,len2);
}
else
{
tmp2 = f1.substr(len1-len+1,len1);
}
sa = f2.c_str();
flag = 0;
for(int j=v-1;j>1;j--)
{
if(sa[0] == 'a')
{
sa = f2.c_str();
flag = 2;
}
else
{
sa = f1.c_str();
flag = 1;
}
}
if(flag == 2 || flag == 0)
{
tmp1 = f2.substr(0,len-1);
}
else
{
tmp1 = f1.substr(0,len-1);
}
tmp = tmp2 + tmp1;
cc[3] = cmp(tmp,str);
sa = f1.c_str();
for(int j=v;j>1;j--)
{
if(sa[0] == 'a')
{
sa = f2.c_str();
flag = 2;
}
else
{
sa = f1.c_str();
flag = 1;
}
}
if(flag == 1 || flag == 0)
{
tmp4 = f1.substr(0,len-1);
}
else
{
tmp4 = f2.substr(0,len-1);
}
tmp = tmp2 + tmp4;
cc[2] = cmp(tmp,str); //ab连接
sa = f1.c_str();
flag = 0;
for(int j=v;j>1;j--)
{
if(flag == 1 || flag == 0)
{
if(sa[len1] == 'b')
{
flag = 1;
sa = f1.c_str();
}
}
else
{
if(sa[len2] == 'a')
{
flag = 2;
sa = f2.c_str();
}
}
}
if(flag == 1 || flag == 0)
{
tmp3 = f1.substr(len1-len+1,len1);
}
else
{
tmp3 = f2.substr(len2-len+1,len2);
}
tmp = tmp3 + tmp1; //ba
cc[1] = cmp(tmp,str);
tmp = tmp3 + tmp4; //bb
cc[0] = cmp(tmp,str);
sa = a2.c_str();
while(sa)
{
if(*sa == 'a')
{
bignum(count,ct[1],256);
}
else
{
bignum(count,ct[0],256);
}
if(!sa[1])
{
memcpy(ct1,count,256);
break;
}
if(sa[1] == 'a' && *sa == 'a')
{
bignum(count,cc[3],256);
}
if(sa[1] == 'a' && *sa == 'b')
{
bignum(count,cc[1],256);
}
if(sa[1] == 'b' && *sa == 'a')
{
bignum(count,cc[2],256);
}
if(sa[1] == 'b' && *sa == 'b')
{
bignum(count,cc[0],256);
}
sa++;
}
}
int flag = 0;
for(int i=0;i<256;i++)
{
int temp = count[i];
if(temp != 0)
flag = 1;
if(flag == 1)
{
cout<<temp;
}
}
}
FIB(1)=b,FIB(2)=a,FIB(k+2)=FIB(k+1)*FIB(k)(k>=1),*的意思是两个字符串连接,所以FIB3=ab;FIB4=aba;FIB5=abaab;
现在给出一个长度最多为30的模式串,仅含字母a或b.
计算第n个Fib单词中含有多少个这样的模式串.模式串在Fib单词中的位置可以重叠.
Input
该题有多组测试数据,每组测试数据2行,第一行是单词.第二行是n,n<=200.
Output
模式串出现的次数.
Sample Input
aba
6
Sample Output
3
对于n>12所有的都可以拆成 n =11和 n= 12 的和
设n = 11的字符串 用 b 代替, n = 12 的用 a 代替则n = 21 n = 22 和 n = 11 ,n = 12 是相同的字符串,只要处理字符串首尾连接处产生的模式匹配即可,好多重复代码可以用函数表示。基本功能实现了。速度也没什么问题。超大数字只简单用了个 256的数组.好像开大了,128就够了
如果对于n=11,n=12 以及他们首尾连接的4种情况,字符串匹配个数为0,那么对于任何n>12匹配个数都为0,下面程序没有对此优化
int cmp(const string& s1,const string& s2)
{
int count=0;
s1.find(s2);
string::size_type fd = s1.find(s2);
while(fd != string::npos)
{
++count;
++fd;
fd = s1.find(s2,fd);
}
return count;
}
//超长数字加 n
void bignum(char* num,int n,int len)
{
int m=0;
for(int i=255;i>0;i--)
{
m = n - n/10*10;
num[i] += m;
if(num[i]>=10)
{
int j = i;
while(num[j]>=10)
{
if(j>len)
{
cout<<"越界"<<endl;
break;
}
num[j--] -= 10;
num[j] += 1;
}
}
n /= 10;
if(n==0)
{
break;
}
}
}
//可以使用128位数组,提高效率
//超长数字相加
void bignum(char* num,char* str,int len)
{
for(int i=255;i>0;i--)
{
num[i] += str[i];
int j = i;
while(num[j]>=10)
{
num[j--] -= 10;
num[j] += 1;
}
}
}
void fib1(string str,int n)
{
string f1="b";
string f2="a";
string f3;
char count[256] = {0};
string f;
string ay;
string a1= "b";
string a2= "a";
char ct[2][256] ={0};
int cc[4] = {0};
char ct1[256],ct2[256];
if(n==0)
f3=f1;
if(n==1)
f3=f2;
int i = 0;
int v = n / 10;
int x = n % 10;
if(v > 0)
{
for(i=2;i<12;i++)
{
f3 = f2 + f1;
f1=f2;
f2 = f3;
}
bignum(ct[1],cmp(f2,str),256);
bignum(ct[0],cmp(f1,str),256);
}
else
{
for(i=2;i<n;i++)
{
f3 = f2 + f1;
f1=f2;
f2 = f3;
}
int tt = cmp(f2,str);
cout<<tt<<endl;
return;
}
string::size_type len2 = f2.length();
string::size_type len1 = f1.length();
string::size_type len = str.length();
for(int i=1;i<v;i++)
{
int flag = 0;
string tmp,tmp1,tmp2,tmp3,tmp4;
const char * sa = f2.c_str();
for(int j=i;j>1;j--)
{
if(flag == 2 || flag == 0)
{
if(sa[len2] == 'b')
{
flag = 1;
sa = f1.c_str();
}
}
else
{
if(sa[len1] == 'a')
{
flag = 2;
sa = f2.c_str();
}
}
}
if(flag == 2 || flag == 0)
{
tmp2 = f2.substr(len2-len+1,len2);
}
else
{
tmp2 = f1.substr(len1-len+1,len1);
}
sa = f2.c_str();
flag = 0;
for(int j=i;j>1;j--)
{
if(sa[0] == 'a')
{
sa = f2.c_str();
flag = 2;
}
else
{
sa = f1.c_str();
flag = 1;
}
}
if(flag == 2 || flag == 0)
{
tmp1 = f2.substr(0,len-1);
}
else
{
tmp1 = f1.substr(0,len-1);
}
tmp = tmp2 + tmp1;
cc[3] = cmp(tmp,str);
sa = f1.c_str();
for(int j=i;j>1;j--)
{
if(sa[0] == 'a')
{
sa = f2.c_str();
flag = 2;
}
else
{
sa = f1.c_str();
flag = 1;
}
}
if(flag == 1 || flag == 0)
{
tmp4 = f1.substr(0,len-1);
}
else
{
tmp4 = f2.substr(0,len-1);
}
tmp = tmp2 + tmp4;
cc[2] = cmp(tmp,str); //ab连接
sa = f1.c_str();
flag = 0;
for(int j=i;j>1;j--)
{
if(flag == 1 || flag == 0)
{
if(sa[len1] == 'b')
{
flag = 1;
sa = f1.c_str();
}
}
else
{
if(sa[len2] == 'a')
{
flag = 2;
sa = f2.c_str();
}
}
}
if(flag == 1 || flag == 0)
{
tmp3 = f1.substr(len1-len+1,len1);
}
else
{
tmp3 = f2.substr(len2-len+1,len2);
}
tmp = tmp3 + tmp1; //ba
cc[1] = cmp(tmp,str);
tmp = tmp3 + tmp4; //bb
cc[0] = cmp(tmp,str);
sa = f1.c_str();
memset(count,0,256*sizeof(char));
while(sa)
{
if(*sa == 'a')
{
bignum(count,ct[1],256);
}
else
{
bignum(count,ct[0],256);
}
if(!sa[1])
{
memcpy(ct1,count,256);
break;
}
if(sa[1] == 'a' && *sa == 'a')
{
bignum(count,cc[3],256);
}
if(sa[1] == 'a' && *sa == 'b')
{
bignum(count,cc[1],256);
}
if(sa[1] == 'b' && *sa == 'a')
{
bignum(count,cc[2],256);
}
if(sa[1] == 'b' && *sa == 'b')
{
bignum(count,cc[0],256);
}
sa++;
}
sa = f2.c_str();
memset(count,0,256*sizeof(char));
while(sa)
{
if(*sa == 'a')
{
bignum(count,ct[1],256);
}
else
{
bignum(count,ct[0],256);
}
if(!sa[1])
{
memcpy(ct2,count,256);
break;
}
if(sa[1] == 'a' && *sa == 'a')
{
bignum(count,cc[3],256);
}
if(sa[1] == 'a' && *sa == 'b')
{
bignum(count,cc[1],256);
}
if(sa[1] == 'b' && *sa == 'a')
{
bignum(count,cc[2],256);
}
if(sa[1] == 'b' && *sa == 'b')
{
bignum(count,cc[0],256);
}
sa++;
}
memcpy(ct[1],ct2,256);
memcpy(ct[0],ct1,256);
}
if( x-2 > 0)
{
memset(count,0,256*sizeof(char));
for(int i=2;i<x;i++)
{
ay = a2+a1;
a1 = a2;
a2 = ay;
}
int flag = 0;
string tmp,tmp1,tmp2,tmp3,tmp4;
const char * sa = f2.c_str();
for(int j=v-1;j>1;j--)
{
if(flag == 2 || flag == 0)
{
if(sa[len2] == 'b')
{
flag = 1;
sa = f1.c_str();
}
}
else
{
if(sa[len1] == 'a')
{
flag = 2;
sa = f2.c_str();
}
}
}
if(flag == 2 || flag == 0)
{
tmp2 = f2.substr(len2-len+1,len2);
}
else
{
tmp2 = f1.substr(len1-len+1,len1);
}
sa = f2.c_str();
flag = 0;
for(int j=v-1;j>1;j--)
{
if(sa[0] == 'a')
{
sa = f2.c_str();
flag = 2;
}
else
{
sa = f1.c_str();
flag = 1;
}
}
if(flag == 2 || flag == 0)
{
tmp1 = f2.substr(0,len-1);
}
else
{
tmp1 = f1.substr(0,len-1);
}
tmp = tmp2 + tmp1;
cc[3] = cmp(tmp,str);
sa = f1.c_str();
for(int j=v;j>1;j--)
{
if(sa[0] == 'a')
{
sa = f2.c_str();
flag = 2;
}
else
{
sa = f1.c_str();
flag = 1;
}
}
if(flag == 1 || flag == 0)
{
tmp4 = f1.substr(0,len-1);
}
else
{
tmp4 = f2.substr(0,len-1);
}
tmp = tmp2 + tmp4;
cc[2] = cmp(tmp,str); //ab连接
sa = f1.c_str();
flag = 0;
for(int j=v;j>1;j--)
{
if(flag == 1 || flag == 0)
{
if(sa[len1] == 'b')
{
flag = 1;
sa = f1.c_str();
}
}
else
{
if(sa[len2] == 'a')
{
flag = 2;
sa = f2.c_str();
}
}
}
if(flag == 1 || flag == 0)
{
tmp3 = f1.substr(len1-len+1,len1);
}
else
{
tmp3 = f2.substr(len2-len+1,len2);
}
tmp = tmp3 + tmp1; //ba
cc[1] = cmp(tmp,str);
tmp = tmp3 + tmp4; //bb
cc[0] = cmp(tmp,str);
sa = a2.c_str();
while(sa)
{
if(*sa == 'a')
{
bignum(count,ct[1],256);
}
else
{
bignum(count,ct[0],256);
}
if(!sa[1])
{
memcpy(ct1,count,256);
break;
}
if(sa[1] == 'a' && *sa == 'a')
{
bignum(count,cc[3],256);
}
if(sa[1] == 'a' && *sa == 'b')
{
bignum(count,cc[1],256);
}
if(sa[1] == 'b' && *sa == 'a')
{
bignum(count,cc[2],256);
}
if(sa[1] == 'b' && *sa == 'b')
{
bignum(count,cc[0],256);
}
sa++;
}
}
int flag = 0;
for(int i=0;i<256;i++)
{
int temp = count[i];
if(temp != 0)
flag = 1;
if(flag == 1)
{
cout<<temp;
}
}
}