修改成递归版本

思路:

  1、设定规则数组,比如:1加一根火柴只可以变成7.

  2、设定方法数组,比如:一个数增加了一根火柴,其他的数必然减少一根火柴。

  3、增加Array方法,由元素名和方法,得到规则对象。

  4、增加替换数组元素的方法,根据原数组和下标,得到 一个字符串。有2个方法,一个深度copy,一个普通指针,这样就可以自由选择是否改变原来的数组了。

  5、主逻辑:

    根据式子生成数组

    遍历数组元素,匹配规则,匹配到,递归进行二次匹配。

    匹配不到规则,递归下一个元素。

      

<html>
<head>
<title>移动一根火柴使等式成立js版本</title>
<meta http-equiv="Content-Type" content="text/html; charset=gbk">
<script language="javascript">
//递归阶乘
function getNum(i){
if (i>1){
return i*getNum(i-1);
}else{
return 1;
}
}
//console.log(getNum(3)); /**
* 规则的设定,按照信号灯样式,8就是由7根火柴棍组成
* 设定变化规则:
* add: 0-》8
* 1-》7
* 3-》9
* 5-》6,9
* 6-》8
* 9-》8
* - -》+,=
* sub: 6-》5
* 7-》1
* 8-》0.6,9
* 9->3,5
* + -> -
* = -> -
* mv: 0 -> 6,9
* 2 -> 3
* 3 -> 5
* 6 -> 9
* 9 -> 0,6
*/
var data = [];
data.push({a:0,b:[8],m:"add"}); //0加一根火柴可以变化为8以此类推
data.push({a:0,b:[6,9],m:"mv"});
data.push({a:1,b:[7],m:"add"});
data.push({a:2,b:[3],m:"mv"});
data.push({a:3,b:[5],m:"mv"});
data.push({a:3,b:[9],m:"add"});
data.push({a:5,b:[6,9],m:"add"});
data.push({a:6,b:[5],m:"sub"});
data.push({a:6,b:[9],m:"mv"});
data.push({a:6,b:[8],m:"add"});
data.push({a:7,b:[1],m:"sub"});
data.push({a:8,b:[0,6,9],m:"sub"});
data.push({a:9,b:[0,6],m:"mv"});
data.push({a:9,b:[3,5],m:"sub"});
data.push({a:9,b:[8],m:"add"});
data.push({a:"+",b:["-"],m:"sub"});
data.push({a:"-",b:["+","="],m:"add"});
data.push({a:"=",b:["-"],m:"sub"}); //修改数组,增加方法 可以由key和method得到唯一的变化规则对象。
Array.prototype.get = function(key, method){
for(var i = 0; i < this.length; i++){
if(this[i].a == key && this[i].m == method){
return this[i];
}
}
} /**
* 转换字符串:将原式子替换成根据规则变换后的式子
* params:
* ori: 原式子
* index: 需要替换的位置
* fin: 根据规则替换的数字
*
* return 替换后的字符串
*/
function changeStr(ori, index, fin){
var str = ori.substr(0, index) + fin + ori.substring(index+1, ori.length);
return str;
} //返回替换后的字符串,并不改变原来数组的值,深度copy
function changeArrMirror(oriArr, index, fin){
var tempArr = oriArr.slice(0);
tempArr[index] = fin;
var str = tempArr.join("");
return str;
} //返回替换后的字符串,并改变原来数组的值,指针copy
function changeArrAll(oriArr, index, fin){
oriArr[index] = fin;
var str = oriArr.join("");
return str;
} /**
* 计算主体方法:以2+3=6为例
* 基本逻辑:得到原字符串数组[2, +, 3, =, 6],从第一位开始,查找规则,
* 匹配到规则,递归下一个元素查找相反规则,构成字符串,查看是否成立,成立则打印,继续程序,查找下一个成立等式
* 匹配不到规则,递归下一个方法元素,都匹配不到,递归下一个式子元素。
* param:
* originArr: 拆分的待匹配的数组
* originIndex: 式子数组的索引,正在匹配的元素下标
* methodIndex: 方法数组的索引
* isChanged: 是否匹配了第一个元素
* return:
*/
function compare(originArr, originIndex, methodIndex, isChanged){
if (originIndex >= originArr.length){
return;
}
if (methodIndex == 2){
isChanged = true;
} //已经匹配第一次的式子,进行第二次匹配,需要得到 methodArr[methodIndex]的成对方法匹配
// 匹配不到规则,递归式子数组的下一个值
// 匹配到规则,循环查看规则的值,看是否有能另等式成立的,如果都不能成立,递归式子数组的下一个值
if(isChanged){
var role = data.get(originArr[originIndex], methodArr[methodIndex][1]);
if (role == undefined || role == null){
compare(originArr, originIndex + 1, methodIndex, isChanged);
}else{
for (var matchIndex=0; matchIndex < role.b.length; matchIndex++){
var changedStr = changeArrMirror(originArr, originIndex, role.b[matchIndex]);
if (eval(changedStr.split("=")[0]) == eval(changedStr.split("=")[1])){
console.log(changedStr);
flag = true;
return;
}
}
compare(originArr, originIndex + 1, methodIndex, isChanged);
}
}else{
//匹配方法数组元素的第一个method,看是否有规则
// 如果有,设定匹配标识isChanged=true,进行二次匹配
// 如果没有,递归下一个式子数组元素。
var role = data.get(originArr[originIndex], methodArr[methodIndex][0]); //如果没有相应rule,匹配方法数组的其他方法,直到都匹配了
if (role == undefined || role == null){
if (methodIndex >= methodArr.length)
compare(originArr, originIndex + 1, 0, isChanged);
else
compare(originArr, originIndex, methodIndex + 1, isChanged);
}else{
for (var matchIndex=0; matchIndex < role.b.length; matchIndex++){
var changedStr = changeArrAll(originArr, originIndex, role.b[matchIndex]);
isChanged = !isChanged;
compare(originArr, originIndex + 1, methodIndex, isChanged);
}
} }
} //方法数组,成对出现
var methodArr = [["add", "sub"], ["sub", "add"], ["mv", "mv"]];
var flag = false; //得到原始式子,分割成数组,调用递归函数进行计算。
function compute(){
var originStr = document.getElementById("origin").value; var baseArr = originStr.split("");
for (var i=0; i<baseArr.length; i++){
var tempBaseArr = baseArr.slice(0);
compare(tempBaseArr, i, 0, false);
}
if (!flag){
console.log("没有匹配答案");
} } </script>
</head>
<body>
输入一个需要计算的式子,例如:1+2+3=6
<input id="origin" onkeypress="if(event.keyCode == 13) compute();"/>
<input type="button" value="计算" onclick="compute()" />
</body>
</html>

移动一根火柴使等式成立js版本(递归)的更多相关文章

  1. 移动一根火柴使等式成立js版本

    <html><head><meta http-equiv="Content-Type" content="text/html; charse ...

  2. 洛谷-火柴棒等式-NOIP2008提高组复赛

    题目描述 Description 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: ...

  3. C语言程序设计100例之(18):火柴棒等式

    例18   火柴棒等式 用n根火柴棍,可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棒拼出的整数(若该数非零,则最高位不能是0).用火柴棒拼数字0~9的拼法如图1所示. 图1  用 ...

  4. NOIP200806 火柴棒等式【B005】

    [B005]火柴棒等式[难度B]———————————————————————————————————————————————————————————— [题目要求] 给你n根火柴棍,你可以拼出多少个 ...

  5. NOIP2008提高组火柴棒等式(模拟)——yhx

    题目描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: 注意: 加号与等号各自 ...

  6. TYVJ P1012 火柴棒等式 Label:枚举

    背景 NOIP2008年提高组第二题 描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法 ...

  7. noip2008 火柴棒等式

    P1149 火柴棒等式 1.9K通过 3.7K提交 题目提供者该用户不存在 标签搜索/枚举模拟2008NOIp提高组 难度普及- 提交该题 讨论 题解 记录   题目描述 给你n根火柴棍,你可以拼出多 ...

  8. 【枚举】Vijos P1496 火柴棒等式 (NOIP2008提高组第二题)

    题目链接: https://vijos.org/p/1496 题目大意: 给你n(n<24)根火柴棍,你可以拼出多少个形如“A+B=C”的等式?("+"和"=&qu ...

  9. 洛谷P1149 火柴棒等式

    题目描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: 注意: 1.加号与等号 ...

随机推荐

  1. JSON文件导入Unity3d中是空的的问题

    将Json文件的内容在网上在线的Json文件编辑器导出后再导入即可

  2. mysql之存储引擎和文件配置

    (查看系统服务,在运行里输入services.msc) 补充:将mysql做成系统服务:mysqld --install 取消:mysqld --romove 在服务中可以直接鼠标操作mysql服务的 ...

  3. Tomcat架构解析(一)-----Tomcat总体架构

    Tomcat是非常常用的应用服务器,了解Tomcat的总体架构以及实现细节,对于理解整个java web也是有非常大的帮助. 一.Server   1.最简单的服务器结构 最简单的服务器结构如图所示: ...

  4. DevExpress 只允许修改指定列

    gridView1.OptionsBehavior.Editable = true; gridView1.OptionsBehavior.ReadOnly = false; foreach (Grid ...

  5. C++IO cin

    cin cin.get() 每次只读缓冲区一个字符,不能接收空格 cin.getline() 读缓冲区一行,能够接收空格 cin.ignore(2) 忽略缓冲器2个字节 int i = cin.pee ...

  6. java并发控制工具类和集合等

    转载自:https://my.oschina.net/hosee/blog/607677 摘要: 本系列基于炼数成金课程,为了更好的学习,做了系列的记录. 本文主要介绍: 1.各种同步控制工具的使用 ...

  7. java中定时器总结

    java实现定时器的四种方式: 一. /** * 延迟20000毫秒执行 java.util.Timer.schedule(TimerTask task, long delay) */ public ...

  8. [指南] 15分钟学会MySQL(Linux版)

    原文链接:http://www.mysqlpub.com/thread-348-1-1.html 原创出处:MySQLpub.com  , 作者:kider  ,转载请注明作者和出处,并不能用于商业用 ...

  9. 动态生成PictureBox控件,涉及:PictureBox控件和flowLayoutPanel面板

    一.概述 flowLayoutPanel面板是一系列控件的容器,有关详细的使用方法留待以后总结. 二.问题提出 问题提出:点击按钮,扫描指定文件夹并将其中的所有图片放在flowLayoutPanel面 ...

  10. NSUserDefaults 添加与删除

    //NSUserDefaults会创建一个plist文件,内部存放一个字典    NSUserDefaults *userDefaults = [NSUserDefaults standardUser ...