function gcd(a,b) { if (b > a) return gcd(b,a) if (a % b == 0) return b return gcd(b, a%b); } function fillOil(maxA,maxB,goal){ //目标不能大于两个容器的容量 if (goal > maxA && goal > maxB)return; //目标必须是两个容器容量最大公约数的倍数 if (goal%gcd(maxA,maxB) != 0) {return}; //初始化容器为空 var items = [{a:0,b:0,ac:"初始化 0:0"}] //初始化游标 var index = 0; //广度遍历全部可能状况 for(;;) { var A = items[index].a; var B = items[index].b; //得到这一步全部可能状况以及操做方法 var steps = [{a:0, b:B, ac:"把A清空"}, {a:A,b:0, ac:"把B清空"}, {a:maxA,b:B, ac:"把A装满"}, {a:A,b:maxB, ac:"把B装满"}, A+B<maxB?{a:0,b:A+B, ac:"把A的液体倒入B中"}:{a:A+B-maxB,b:maxB, ac:"把A的液体倒入B中"}, A+B<maxA?{a:A+B,b:0, ac:"把B的液体倒入A中"}:{a:maxA,b:A+B-maxA, ac:"把B的液体倒入A中"} ]; var goals = steps.filter(function(item){return item.a == goal || item.b==goal}) //发现目标,中止遍历 if(goals.length){ var item = goals[0]; item.parent = items[index]; return item; } //把新生成而且没有出现过的的步骤加入遍历池 steps.forEach(function(itemInStep){ if (!items.some(function(item){return item.a == itemInStep.a && item.b == itemInStep.b})) { itemInStep.parent = items[index] items.push(itemInStep); }; }) index++; } } //打印操做步骤 function print(item){ if (!item) {console.log("无解");return;}; if (item.parent) { print(item.parent); console.log(item.ac + ",获得 " + item.a + " : " + item.b); } else console.log(item.ac); } function test(maxA, maxB, goal){ print(fillOil(maxA,maxB,goal)); } test(7,3,5)