【问题描述】
匪警请拨110,即使手机欠费也可拨通!
为了保障社会秩序,保护人民群众生命财产安全,警察叔叔需要与罪犯斗智斗勇,因而需要经常性地进行体力训练和智力训练!
某批警察叔叔正在进行智力训练:
1 2 3 4 5 6 7 8 9 = 110
请看上边的算式,为了使等式成立,需要在数字间填入加号或者减号(可以不填,但不能填入其它符号)。之间没有填入符号的数字组合成一个数,例如:12+34+56+7-8+9 就是一种合格的填法;123+4+5+67-89 是另一个可能的答案。
请你利用计算机的优势,帮助警察叔叔快速找到所有答案。每个答案占一行。形如:
12+34+56+7-8+9
123+4+5+67-89
第一种方式,遍历尝试所有的公式,并计算出结果
public class Main {
public static void main(String[] args){
String nums = new String("123456789");
All(nums,1);
}
// 0 1 递归问题。设计递归考虑测试方案。每两个数的中间可以加 - 号 可以 + 号 可以 啥都没有(连接)
public static void All(String nums,int index){
//第八个位置填充完毕
if(index==9){
//判断是否等于110
if(calc(nums)){
System.out.println(nums);
};
return;
}
//将1替换成1+
All(nums.replace(index+"",index+"+"),index+1);
All(nums.replace(index+"",index+"-"),index+1);
All(nums,index+1);
}
public static boolean calc(String nums){
//先把- 号分割开
String[] sub = nums.split("\\+");
int count = 0 ;
for(int i=0;i<sub.length;i++){
int temp = 0;
//没有减号的存在,是一个完整的数
if(sub[i].indexOf('-')==-1){
temp = Integer.parseInt(sub[i]);
}else{
//有减号
String[] add = sub[i].split("-");
temp = Integer.parseInt(add[0]);
for(int j=1;j<add.length;j++){
temp -= Integer.parseInt(add[j]);
}
}
count += temp;
}
return count == 110;
}
//第二种计算方式。原理,数字和符号的数量
public static boolean calc2(String form){
//把数字隔离出来
String[] nums = form.split("[\\+|-]");
//得到所有符号
String fus = form.replaceAll("\\d*","");
int num = Integer.parseInt(nums[0]);
for(int i=1;i<nums.length;i++){
switch (fus.charAt(i-1)) {
case '-':
num -= Integer.parseInt(nums[i]);
break;
case '+':
num += Integer.parseInt(nums[i]);
break;
}
}
return num == 110;
}
}
第二种方式:一边深度搜索,一边累加
遍历的时候老规矩。
有加,有减,有连接到一起的数。
有一个要点。必须倒着去构造公式。 原因。1 不存在 -1 ,
深度搜索切记一定要回溯
public class Main{
public static void main(String[] args){
int[] nums = {1,2,3,4,5,6,7,8,9};
f(nums,8,"",0);
}
public static void f(int[] nums,int index,String rex,int count){
if(index==0){
if(count+nums[0]==110){
System.out.println(nums[0]+rex);
}
return;
}
f(nums,index-1,"+"+nums[index]+rex,count+nums[index]);
f(nums,index-1,"-"+nums[index]+rex,count-nums[index]);
int sign = nums[index-1];
nums[index-1] = Integer.parseInt(sign+""+nums[index]);
f(nums,index-1,rex,count);
//回溯
nums[index-1] = sign;
}
}