求字典序在s1和s2之间的,长度在len1到len2的字符串的个数,结果mod 1000007。

/**********************************************************************************************************************************************
*   题目描述:
*   求字典序在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;//可能出现两个字串完全一样
	}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值