1 2 3 4 5 6 7 8 9 = 110,在数字间填入加号或者减号(可以不填,但不能填入其它符号)使等式成立。

时间:2022-11-05 15:02:52
一共有3^8种可能。
答案:
成功:12+34+56+7-8+9 = 110
成功:12+3+45+67-8-9 = 110
成功:12-3+4-5+6+7+89 = 110
成功:1+2+34+5+67-8+9 = 110
成功:1-2+3+45-6+78-9 = 110
成功:123+4-5-6-7-8+9 = 110
成功:123-4+5-6-7+8-9 = 110
成功:123-4-5+6+7-8-9 = 110
成功:123+4+5+67-89 = 110
成功:1+234-56-78+9 = 110


两种方法:


/**
 * Copyright (C) 2012 Lear C
 */

/**
 * 1 2 3 4 5 6 7 8 9 = 110 
 * <p/> 
 * 在数字间填入加号或者减号(可以不填,但不能填入其它符号)使等式成立。 <br/>
 * 一种更好的方法是:<br/>
 * 每一个空隙之间都有三种可能,"+", "-", "",所以一共有3^8种可能。
 * 
 * @author Lear
 */
public class Tester2 {
	
	private static final char[] NUMBERS = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};  
	private static final String[] OPERATORS = {"+", "-", ""};
    private static final int RESULT = 110;  // 计算结果  

	public static void main(String[] args) {
		sortAndCompute(0, "");
	}

	private static void sortAndCompute(int numIndex, String buffer) {
		// 说明到最后一个字符了
		if(numIndex == NUMBERS.length - 1) {
			buffer += NUMBERS[numIndex];
			String formula = buffer.toString();
			if(sum(formula) == RESULT) {
				System.out.println(formula + " = " + RESULT);
			}
			return;
		}
		
		for(int operIndex = 0; operIndex < OPERATORS.length; ++operIndex) {
			buffer += NUMBERS[numIndex];
			buffer += OPERATORS[operIndex];
			sortAndCompute(numIndex + 1, buffer);
			// 消除前面两个已经添加的字符恢复原状,以便下一次循环的叠加
			// 但是当中间连接符变为''的时候,则只删除buffer中的前面一个字符
			buffer = operIndex != 2 ? buffer.substring(0, buffer.length() - 2)
					: buffer.substring(0, buffer.length() - 1);
		}
	}
	
	private static int sum(String formula) {
		if(formula == null || formula.trim().length() == 0)
			throw new IllegalArgumentException("formula is invalid!");
		
		Stack<String> numStack = new Stack<String>();
		Stack<String> operStack = new Stack<String>();
		StringBuffer numBuffer = new StringBuffer();
		
		formula += "#";	// 添加一个结束符到公式末尾便于计算
		char[] chs = formula.toCharArray();
		for(int index = 0; index < formula.length(); ++index) {
			if(chs[index] != '+' && chs[index] != '-' && chs[index] != '#') {
				numBuffer.append(chs[index]);
			} else {
				numStack.push(numBuffer.toString());
				numBuffer.delete(0, numBuffer.length());
				
				if(operStack.isEmpty()) operStack.push(chs[index] + "");
				else {
					int numAft = Integer.parseInt(numStack.pop());
					int numBef = Integer.parseInt(numStack.pop());
					String oper = operStack.pop();
					int sum = oper.equals("+") ? numBef + numAft : numBef - numAft;
					numStack.push(sum + "");
					operStack.push(chs[index] + "");
				}
			}
		}
		return Integer.parseInt(numStack.pop());
	}
}



package test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 1 2 3 4 5 6 7 8 9 = 110
 * <p/>
 * 在数字间填入加号或者减号(可以不填,但不能填入其它符号)使等式成立。
 * @author Lear
 *
 */
public class Tester {

	private static final char[] NUMBERS = {'1', '2', '3', '4', '5', '6', '7', '8', '9'/**/};
	private static final int RESULT = 110;	// 计算结果
	
	public static void main(String[] args) {
		List<List<String>> all = sort(NUMBERS);
		testPrint(all);
		for(List<String> aRank : all) {
			printEstablishEquation(aRank);
		}
	}
	
	private static void testPrint(List<List<String>> all) {
		for(List<String> aRank : all) {
			System.out.println(aRank);
		}
	}

	/**
	 * 按nums的顺序进行排列组合,最后返回一个List数组,它将包含所有的可能的一个由一列数据的List数组。
	 * <p/>
	 * 此为一个递归函数,第一个的组合数字后面的字符都将继续调用此函数以计算出List<List<String>>.<br/>
	 * 缺点:数据量增大时,将导致内存溢出,而且算法的效率低下
	 * 
	 * @param nums
	 * @return 格式:[[1,2,3,4..],[12,3,4,..],[12,34,...],....]
	 */
	private static List<List<String>> sort(char[] nums) {
		if(nums.length == 0) return Collections.emptyList();
		
		List<List<String>> all = new ArrayList<List<String>>();
		// 字符数组直接加入此List中
		List<String> firstRank = new ArrayList<String>();
		for(int i = 0; i < nums.length; ++i) {
			firstRank.add(nums[i] + "");
		}
		all.add(firstRank);
		
		// 组合数字的个数,如:1,2,3,4.... ; 12,3,4,5.. ; 123,4,5.. ; 1234.5 ...
		for(int combinationNum = 2; combinationNum <= nums.length; ++combinationNum) {
			// 此组合的偏移量,如:12,3.... ; 1,23,4....; 1,2,34,...
			for(int offset = 0; offset < nums.length - (combinationNum - 1); ++offset) {
				List<String> preRank = new ArrayList<String>();
				StringBuilder buffer = new StringBuilder();
				
				for(int i = 0; i < offset; ++i) {	// 前
					preRank.add(nums[i] + "");
				}
				
				for(int i = offset; i < offset + combinationNum; ++i) {	// 中
					buffer.append(nums[i]);
				}
				preRank.add(buffer.toString());
				
				// 获取后面的字符数组,然后递归组合
				char[] suffix = new char[nums.length - (offset + combinationNum)];
				for(int i = offset + combinationNum, index = 0; i < nums.length; ++i, ++index) {	// 后
					suffix[index] = nums[i];
				}
				// 例如:12组合的后面 [[3,4,5,6,7...],[34,5,6...],[345...]]
				List<List<String>> sufArray = sort(suffix);
				// 为里面的所有List<String>添加前面的数字组合,
				// 例如:添加12到上面的例子中,使之成为[[12,3,4,...],[12,34...]....]
				if(sufArray.size() != 0)
					for(List<String> sufRank : sufArray) {
						// 组合前后的List
						List<String> allRank = new ArrayList<String>();
						for(int i = 0; i < preRank.size(); ++i) allRank.add(preRank.get(i));
						for(int i = 0; i < sufRank.size(); ++i) allRank.add(sufRank.get(i));
						// 添加到all中去
						all.add(allRank);
					}
				else
					all.add(preRank);	// 说明到末尾了
			}
		}
		return all;
	}

	private static void printEstablishEquation(List<String> ls) {
		char[] operators = {'+', '-'};
		StringBuilder buff = new StringBuilder();
		
		// 转换为数字
		int[] nums = new int[ls.size()];
		for(int i = 0; i < ls.size(); ++i) {
			nums[i] = Integer.parseInt(ls.get(i));
		}
		// 对应的操作符是否变化的数组
		boolean[] isOperChanges = new boolean[nums.length - 1];
		// 计算每一个isOperChange的变化周期
		int[] perOperChangeCounts = new int[isOperChanges.length];
		for(int index = 0; index < isOperChanges.length; ++index) {
			perOperChangeCounts[index] = (int) Math.pow(2, index);
		}
		// 可能性的计算次数 2^(nums.length - 1)
		int computeCount = (int) Math.pow(2, nums.length -1);
		for(int i = 1; i <= computeCount; ++i) {
			// 迭代计算
			int sum = nums[0];
			buff.append(nums[0]);
			for(int index = 0; index < nums.length - 1; ++index) {
				sum = isOperChanges[index] ? sum - nums[index + 1] : sum + nums[index + 1];
				buff.append(isOperChanges[index] ? operators[1] : operators[0]);
				buff.append(nums[index + 1]);
			}
			// 打印
			if(sum == RESULT)	// 输出等式成立的表达式
				System.out.println("成功:" + buff.toString() + " = " + sum);
//			else
//				System.out.println("失败:"  + buff.toString() + " = " + sum);
			buff.delete(0, buff.length());
			
			// 操作符交替变化数组的迭代计算。
			// 第1操作符,每次交替变化;第2操作符,i每 2^2次变化一次;第3操作符,i每2^3次变化一次
			for(int index = 0; index < isOperChanges.length; ++index) {
				if(i % perOperChangeCounts[index] == 0) 
					isOperChanges[index] = !isOperChanges[index];	// 交替
			}
		}
		
	}
}