百度2012校招笔试题之位数和编码


给定一个数字编码N,大多数情况下可以找到一个数字编码M,其位数与编码N相等(编码可以从0开始),各位数字之和与编码N中各位数字之和相等,并且M是数值大于N的所有码中最小的一个,也可能要找的编码M不存在。

如给定编码N=134,则编码M=143;给定编码N=020,则编码M=101,形式化表述为f(N)=M,如果M不存在,则

f(N)=-1。

现在给定一个起始编码N, 
N的数字位数最大不超过1000,N 
的数值最大不超过10^500,要求给出序列S(N),其中S(0)=N,S(1)=f(N),S(2)=f(S(1)),S(3)=f(S(2))...,当S(i+1)<0时序列结束,但小于0的元素不包含在序列中,要求给出算法思路和函数。



package test;

public class BaiduCode {
private String n= "030"; //生成编码大于n的最小的编码
private int sum(String s){ //求数字各个位数之和
int sum = 0;
for(int i =0; i < s.length(); i++)
sum += Integer.valueOf(s.charAt(i)+"");
return sum;
}


/*
* 从倒数第二位开始,处理子串sunString(i),尝试把第i位加1(置为x),然后将子串各个位数之和减去x,
* 如果够减,生成一个最小的数,拼接在后面即可;如果不够减,i++,处理考虑下一个子串。
*/
private String compute(String n){
for(int i = n.length()-2; i >=0 ; i--){
String t = n.substring(i);
String re = "";
if(Integer.valueOf(t.charAt(0)+"") < 9){
if(Integer.valueOf(t.charAt(0)+"")+1 > sum(t))
continue;
re += n.substring(0, i);
re +=( Integer.valueOf(t.charAt(0)+"")+1);
re += createMin(sum(t.substring(1))-1, t.length()-1);
return re;
}else{
;
}
}
return "-1";
}

//生成和为sum,长度为len的最小的编码
private String createMin(int sum, int len){
int pos = 0;
String tR = "";
while(sum > 0 && pos < len){
tR+=(sum >= 9)?9:sum;
pos++;
sum-=(sum >= 9)?9:sum;
}
while(pos < len){
tR +="0";
pos++;
}
tR = reverseString(tR);
return tR;
}
private String reverseString(String s){
String r="";
for(int i = s.length()-1; i >=0; i--)
r+=s.substring(i, i+1);
return r;
}
public static void main(String args[]){
BaiduCode bc = new BaiduCode();
String result = bc.compute(bc.n);
System.out.println(result);
}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值