/**********************************************************************************************************************************************
* 题目描述:
* 求字典序在s1和s2之间的,长度在len1到len2的字符串的个数,结果mod 1000007。
输入描述:
每组数据包涵s1(长度小于100),s2(长度小于100),len1(小于100000),len2(大于len1,小于100000)
输入例子:
ab ce 1 2
输出例子:
56
* 题目描述:
* 求字典序在s1和s2之间的,长度在len1到len2的字符串的个数,结果mod 1000007。
输入描述:
每组数据包涵s1(长度小于100),s2(长度小于100),len1(小于100000),len2(大于len1,小于100000)
输入例子:
ab ce 1 2
输出例子:
56
*******************************************************************************************************************************************/
实现代码:
public static void test11()
{
Scanner sc=new Scanner(System.in);
String s1=sc.next();
String s2=sc.next();
int len1=sc.nextInt();
int len2=sc.nextInt();
System.out.println(countTest(s1,s2,len1,len2));
}
public static int countTest(String s1,String s2,int len1,int len2)
{
char t_s1[];//排序在后面的字串
char t_s2[];//排序在前面的字串
//保证t_s1中存放的是字典书序靠前的字符串,t_s2是靠后的字符串
if(s1.compareTo(s2)<0)//s1排序位于s2之前
{
t_s1=s1.toCharArray();
t_s2=s2.toCharArray();
}
else
{
t_s1=s2.toCharArray();
t_s2=s1.toCharArray();
}
int num=0;
int len;
for(int j=len1;j<=len2;j++)
{
len=j;
if(t_s1.length==t_s2.length)
{
num+=countAB(t_s1,t_s2,len);
if(len<Math.min(t_s1.length, t_s2.length))//当之间字符串的长度小于len,排序靠后字串属于中间的数,需要+1
num=num+1;
}
else if(t_s1.length<t_s2.length)//排序靠前的字串短
{
char temp_s[]=new char[len];
if(len>=s1.length())
{
for(int i=0;i<t_s1.length;i++)
{
temp_s[i]=t_s1[i];
}
for(int i=t_s1.length;i<len;i++)
{
temp_s[i]='a';
}
}
else
{
for(int i=0;i<len;i++)
{
temp_s[i]=t_s1[i];
}
}
num+=countAB(temp_s,t_s2,len);
if(len==t_s2.length||len==t_s1.length||len<Math.min(t_s1.length, t_s2.length))//当之间字符串的长度小于len,排序靠后字串属于中间的数,需要+1
num=num+1;
else if(len>Math.min(t_s1.length, t_s2.length)&&len<Math.max(t_s1.length, t_s2.length))
{
num=num+2;//因为两端的值可以取到
}
}
else if(t_s1.length>t_s2.length)//排序靠前的字串长
{
char temp_s[]=new char[len];
if(len>=t_s2.length)
{
for(int i=0;i<t_s2.length;i++)
{
temp_s[i]=t_s2[i];
}
for(int i=t_s2.length;i<len;i++)
{
temp_s[i]='a';
}
}
else
{
for(int i=0;i<len;i++)
{
temp_s[i]=t_s2[i];
}
}
num+=countAB(t_s1,temp_s,len);
if(len<Math.min(t_s1.length, t_s2.length))//当之间字符串的长度小于len,排序靠后字串属于中间的数,需要+1
num=num+1;
}
}
return num;
}
public static int countAB(char []s1,char []s2,int len)
{
int num=0;
len=len-1;//从长度变换成索引的边界
int c=0;//来自低位的借位
int c1=0;//向高位的借位
int base=1;
while(len>=0)
{
if(s2[len]-s1[len]+c>=0) c1=0;
else c1=-1;
if(c1==0)//没有向高位借位
{
num=num+(s2[len]-s1[len]+c)*base;
}
else
{
num=num+(s2[len]-s1[len]+26+c)*base;
}
len--;
base=base*26;
c=c1;//更新来自低位的借位
}
num=num-1;//中间的个数,差值减1
return num>0?num:0;//可能出现两个字串完全一样
}