四则运算4(完结)
2016-04-02 12:26
281 查看
终于熬出头了
php版的四则运算出炉了
由于c++代码转php代码有个BUG调不出来,在经历了10+个小时的努力,换了n+个环境了,终于也没把php断点调试环境搭起来,
所以,就当这是个阉割版的四则运算吧。。。。
首先,环境:
WampServer 3.0 64bit 真方便哈哈哈
netbeans 8.1
然后,数据库设计,
三个表:用户表user,管理员表admin,答题记录表ansrecord
表结构在这里 ↓↓↓
再然后,用户部分:
包括用户登录,用户注册,用户首页三个页面,可实现用户注册,登陆,注销,跳转到在线答题,访问隔离(好像叫这么个名字)等功能,
接下来是管理员部分:
包括 管理员登录,管理员首页,用户列表,答题记录列表四个页面,可实现管理员的登录,注销,查看用户列表,删除特定用户,查看答题记录,删除指定答题记录等功能。
最后,在线答题部分:
这部分就是核心,尴尬
包括OJ首页,设置题目各种属性,题目列表页面,旧题浏览页面,可实现题目属性设定,服务器端生成题目,旧题浏览,保存答题结果等功能。
题目生成是questionGenerator这个类完成的。
由于xdebug+netbeans/phpstrom/sublime/zendstudio 什么什么的环境弄不起来,所以在线判断这部分功能就阉了。。 其实写好了调了好久调不对。。
贴一下核心代码,嘿嘿嘿
基本思路和c++版的相同,不过php 数组的特性,还有字符串处理的优势,还是更方便一些,代码少了一半。
数据库连接用的是PDO,虽然比直接用mysql_* 的函数麻烦一点,但是安全性更高,
访问隔离(貌似是这么叫的)在每一部分都有,通过
或者
实现,简单。
管理员部分对特定数据操作是在遍历中加入GET请求实现的
例如:
从用户界面->OJ首页->OJ->题目属性设置->题目列表->提交题目和答案到数据库
题目属性设置页面提交一个POST表单,通过PHP输入过滤器对表单内容过滤,然后将属性做参数传入questionGenerator构造函数
将题目通过只读的input框 显示,答案也用表单收集,题目数量通过一个隐藏域传入表单
第一次用php做,边做边学,如有错误,感谢指出。
我的队友 信1301-1 刘伟
1.系统首页
2.用户登录
3.用户首页
4.答题设置页面
5.开始答题
6.浏览答题记录
7.管理员登陆界面
8.管理员首页
9.用户管理列表
10.用户答题记录:
php版的四则运算出炉了
由于c++代码转php代码有个BUG调不出来,在经历了10+个小时的努力,换了n+个环境了,终于也没把php断点调试环境搭起来,
所以,就当这是个阉割版的四则运算吧。。。。
首先,环境:
WampServer 3.0 64bit 真方便哈哈哈
netbeans 8.1
然后,数据库设计,
三个表:用户表user,管理员表admin,答题记录表ansrecord
表结构在这里 ↓↓↓
/* Navicat MySQL Data Transfer Source Server : tp Source Server Version : 50709 Source Host : localhost:3306 Source Database : 2zhuzi Target Server Type : MYSQL Target Server Version : 50709 File Encoding : 65001 Date: 2016-03-31 16:22:23 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `admin` -- ---------------------------- DROP TABLE IF EXISTS `admin`; CREATE TABLE `admin` ( `adminid` int(11) NOT NULL AUTO_INCREMENT, `adminname` varchar(255) NOT NULL, `pwd` varchar(255) NOT NULL, PRIMARY KEY (`adminid`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1; -- ---------------------------- -- Records of admin -- ---------------------------- INSERT INTO `admin` VALUES ('1', 'admin', '123456'); INSERT INTO `admin` VALUES ('2', 'root', '123456'); -- ---------------------------- -- Table structure for `ansrecord` -- ---------------------------- DROP TABLE IF EXISTS `ansrecord`; CREATE TABLE `ansrecord` ( `ansrecordid` int(11) NOT NULL AUTO_INCREMENT, `userid` int(11) NOT NULL, `question` varchar(255) NOT NULL, `rightans` double NOT NULL, `lastans` varchar(255) NOT NULL, PRIMARY KEY (`ansrecordid`), KEY `userid` (`userid`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -- ---------------------------- -- Records of ansrecord -- ---------------------------- -- ---------------------------- -- Table structure for `user` -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `userid` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) NOT NULL, `pwd` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, PRIMARY KEY (`userid`) ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
再然后,用户部分:
包括用户登录,用户注册,用户首页三个页面,可实现用户注册,登陆,注销,跳转到在线答题,访问隔离(好像叫这么个名字)等功能,
接下来是管理员部分:
包括 管理员登录,管理员首页,用户列表,答题记录列表四个页面,可实现管理员的登录,注销,查看用户列表,删除特定用户,查看答题记录,删除指定答题记录等功能。
最后,在线答题部分:
这部分就是核心,尴尬
包括OJ首页,设置题目各种属性,题目列表页面,旧题浏览页面,可实现题目属性设定,服务器端生成题目,旧题浏览,保存答题结果等功能。
题目生成是questionGenerator这个类完成的。
由于xdebug+netbeans/phpstrom/sublime/zendstudio 什么什么的环境弄不起来,所以在线判断这部分功能就阉了。。 其实写好了调了好久调不对。。
贴一下核心代码,嘿嘿嘿
<?php class questionGenerator { private $itemNum = 5; private $isMulandDiv = true; private $isParentheses = true; private $isNeg = true; private $isRem = true; private $start = 0; private $end = 100; public $items = array(); function __construct($itemNum, $isMulandDiv, $isParentheses, $isNeg, $isRem, $start, $end) { $this->itemNum = $itemNum; $this->isMulandDiv = $isMulandDiv; $this->isParentheses = $isParentheses; $this->isNeg = $isNeg; $this->isRem = $isRem; $this->start = $start; $this->end = $end; } function isTrueFraction($numerator,$denominator){ //判断产生的分数是否是真分数 if($numerator >= $denominator){ return false; } for($i = 2; $i <= $numerator;$i++){ //判断分数是否能够约分 if(($numerator % $i == 0)&&($denominator % $i == 0)){ return false; } } return true; } function getNum($start = 0, $end = 100,$isParentheses = false,$depth = 0){ // 若带括号 则为 a op ( b op c ) 的形式 op为运算符 if($isParentheses){ $num1 = mt_rand($start,$end); if($depth < 2){ //控制递归层数,带括号的式子少于10个 $num2 = "( " . $this->getNum($start,$end,mt_rand() % 2 == 0,$depth + 1) . " )"; return strval($num1) . " , " . $num2; }else{ $num2 = "( " . $this->getNum($start,$end,false,$depth + 1) . " )"; return strval($num1) . " , " . $num2; } }else{ if(mt_rand() % 7 == 0){ //若随机数n是7的倍数,产生一个真分数和一个整数,否则为两个整数 $num1 = mt_rand($start,$end); $num2 = mt_rand($start,$end); $num3 = mt_rand($start,$end); if($this->isTrueFraction($num1,$num2)){ return strval($num1) . "/" . strval($num2) . " , " . strval($num3); }else{ return $this->getNum($start,$end); } }else{ $num1 = mt_rand($start,$end); $num2 = mt_rand($start,$end); return strval($num1) . " , " . strval($num2); } } } function getOperator($num2 = '1',$isMulandDiv = true){ // 默认第二个参数不为0,默认包括乘除法 $op = array('+','-','*','/'); if($isMulandDiv){ if($num2 == '0'){ //避免除数为0 return $op[mt_rand() % 3]; }else{ return $op[mt_rand() % 4]; } }else{ return $op[mt_rand() % 2]; } } function isNegative($num1, $num2, $op){ if($op == '-'){ if(intval($num1) < intval($num2)){ return true; }else{ return false; } }else{ if(intval($num1) + intval($num2) < 0){ return true; }else{ return false; } } } function isRemainder($num1, $num2){ if(intval($num1) % intval($num2) == 0){ return false; }else{ return true; } } function generateQuest(){ $addFlag = false; $one = 1; while (count($this->items) < $this->itemNum){ $num = $this->getNum($this->start,$this->end,$this->isParentheses); while (strpos($num,",")){ $addFlag = true; if(substr($num,intval(strpos($num,",")) + 2,1) == '('){ //运算符后紧跟括号,运算符选取只和isMulandDiv有关 $op = $this->getOperator('1',$this->isMulandDiv); $num = str_replace(",",$op,$num,$one); }else{ //运算符后是数字,运算符选取和num2和isMulandDiv有关,此时是不带括号或最右边的算式 $num2 = substr($num, intval(strrpos($num,",")) + 2, intval(strpos($num,")")) - intval(strrpos($num,",")) - 3); $op = $this->getOperator($num2,$this->isMulandDiv); $num = str_replace(",", $op, $num, $one); $begin = 0; //找到形如 a op b 的式子 if(strpos($num, "(")){ //如果式子里有()的话 $begin = intval(strrpos($num, "(")) + 2; } $num1 = substr($num, $begin, intval(strrpos($num, $op)) - $begin - 1); if( $op == '-' || $op == '+') { if(!$this->isNeg && $this->isNegative($num1, $num2, $op)) { $addFlag = FALSE; break; } }elseif ($op == '/') { if(!$this->isRem && $this->isRemainder($num1, $num2)){ $addFlag = FALSE; break; } } } } if(!$addFlag){ //满足要求,可以添加 continue; } if(!in_array($num, $this->items)){ //判断是否重复,不重复则添加 array_push($this->items, $num); } } } function calculate($num1,$num2,$op){ switch ($op){ case "+": return $num1 + $num2; break; case "-": return $num1 - $num2; break; case "*": return $num1 * $num2; break; case "/": return $num1 / $num2; break; default : echo "<script>alert('Calculate Error !!!');location='setattr.php';</script>"; } } function getResult(){ $pri = array( '+' => array('+' => '>', '-' => '>', '*' => '<', '/' => '<', '(' => '<', ')' => '>', '#' => '>'), '-' => array('+' => '>', '-' => '>', '*' => '<', '/' => '<', '(' => '<', ')' => '>', '#' => '>'), '*' => array('+' => '>', '-' => '>', '*' => '>', '/' => '>', '(' => '<', ')' => '>', '#' => '>'), '/' => array('+' => '>', '-' => '>', '*' => '>', '/' => '>', '(' => '<', ')' => '>', '#' => '>'), '(' => array('+' => '<', '-' => '<', '*' => '<', '/' => '<', '(' => '<', ')' => '=', '#' => ''), ')' => array('+' => '>', '-' => '>', '*' => '>', '/' => '>', '(' => '', ')' => '>', '#' => '>'), '#' => array('+' => '<', '-' => '<', '*' => '<', '/' => '<', '(' => '<', ')' => '', '#' => '=') ); $ansL = array(); foreach ($this->items as $exp){ $stackOps = array(); $stackNums = array(); array_push($stackOps,"#"); $exp = $exp . " #"; $flag = -1; while (!(substr($exp,$flag + 1,1) == "#" && end($stackOps) == "#")){ $str = substr($exp, $flag + 1, strpos($exp, " ", $flag + 1) - $flag -1); if(!in_array($str,array("+","-","*","/","(",")","#"))){ if(strpos($str,"/")){ $numerator = substr($str,0,strpos($str,"/")); $denominator = substr($str,strpos($str,"/") + 1); array_push($stackNums,floatval($numerator)/floatval($denominator)); $flag = strpos($exp," ",$flag + 1); } else { array_push($stackNums,floatval($str)); $flag = strpos($exp," ",$flag + 1); } } else { if($pri[end($stackOps)][$str] == "<"){ array_push($stackOps,$str); $flag = strpos($exp," ",$flag + 1); }elseif ($pri[end($stackOps)][$str] == ">") { $op = end($stackOps); array_pop($stackOps); $num2 = end($stackNums); array_pop($stackNums); $num1 = end($stackNums); array_pop($stackNums); array_push($stackNums, $this->calculate($num1, $num2, $op)); }elseif ($pri[end($stackOps)][$str] == "=") { array_pop($stackOps); $flag = strpos($exp," ",$flag + 1); } else { echo "<script>alert('Push&Pop Error !!!');location='setattr.php';</script>"; } } } array_push($ansL, end($stackNums)); } return $ansL; } function getQuestionList(){ return $this->items; } }
基本思路和c++版的相同,不过php 数组的特性,还有字符串处理的优势,还是更方便一些,代码少了一半。
数据库连接用的是PDO,虽然比直接用mysql_* 的函数麻烦一点,但是安全性更高,
访问隔离(貌似是这么叫的)在每一部分都有,通过
session_start(); if(!isset($_SESSION['adminid']) && !isset($_SESSION['adminname']) ){ echo "<script>alert('请登录!');location='adminlogin.html';</script>"; }
或者
session_start(); if (!isset($_SESSION['adminid']) && !isset($_SESSION['adminname'])) { echo "<script>alert('请登录!');location='adminlogin.html';</script>"; }
实现,简单。
管理员部分对特定数据操作是在遍历中加入GET请求实现的
例如:
<?php $stmt = $pdo->prepare("select * from ansrecord"); $stmt->execute(); $res = $stmt->fetchAll(PDO::FETCH_ASSOC); ?> <table border="1" align="center" width="40%" > <tr><th>序号</th><th>用户ID</th><th>题目</th><th>最后答案</th><th>操作</th></tr> <tr><td></td><td></td></tr> <?php foreach ($res as $key => $value) { echo "<tr><td>" . $key . "</td><td>" . $value['userid'] . "</td><td>" . $value['question'] . "</td><td>".$value['lastans']."</td><td><a href=\"ansrecordmangagement.php?action=DELETE&ansrecordid=".$value['ansrecordid']."\" >删除记录</a></td></tr>"; } $stmt = null; $pdo = null; ?> </table>
从用户界面->OJ首页->OJ->题目属性设置->题目列表->提交题目和答案到数据库
题目属性设置页面提交一个POST表单,通过PHP输入过滤器对表单内容过滤,然后将属性做参数传入questionGenerator构造函数
$qG = new questionGenerator($itemNum, $isMulandDiv, $isParentheses, $isNeg, $isRem, $start, $end); $qG->generateQuest(); $qL = $qG->getQuestionList(); $numofqL = count($qL);
将题目通过只读的input框 显示,答案也用表单收集,题目数量通过一个隐藏域传入表单
<form method="post" action="submitquestandans.php"> <table> <tr><th>题目</th><th>答案</th></tr> <?php echo "<tr><td colspan=\"2\"><input type=\"hidden\" value=\"".$numofqL."\" name=\"numofqL\" > </td></tr>"; foreach ($qL as $key => $value) { echo "<tr><td><input type=\"text\" name=\"question".$key."\" value=\"".$value."\" readonly=\"true\" ></td><td><input type=\"text\" name=\"answer".$key."\" required size=\"10\" ></td></tr>"; } ?> <tr><td colspan="2"><input type="submit" name="qL_submit" value="提交" ></td></tr> </table> </form>
第一次用php做,边做边学,如有错误,感谢指出。
我的队友 信1301-1 刘伟
1.系统首页
2.用户登录
3.用户首页
4.答题设置页面
5.开始答题
6.浏览答题记录
7.管理员登陆界面
8.管理员首页
9.用户管理列表
10.用户答题记录:
相关文章推荐
- 安卓虚拟定位使用教程
- 安装xampp时提示找不到文件“-n”,提示没有安装Microsoft Visual C++ 2008 Redistributable Package (x86)
- 楼梯有n阶台阶,上楼可以一步上1阶,2阶,3阶,编程序计算共有多少种不同的走法?
- PHP开发APP接口(一)
- Windows Dev Intro - VS2013 Compile X64 Project Upgraded from Win32 Project
- 大端(Big Endian)与小端(Little Endian)详解
- js中 中括号和.的区别
- arch firefox
- Cotex-M3权威指南学习笔记--NVIC与中断控制一
- IPv6套接字地址结构
- 学习进度条——第五周
- 动态内存管理
- 记一些想法
- js获取浏览器body或窗宽度高度
- 12.遍历二叉树与二叉树的建立
- lightoj 1011 - Marriage Ceremonies(状态压缩dp)
- 软件应该使用中文版还是外文版
- 算法总结(1)冒泡排序
- linux修改文件属主以及文件权限
- 获取canvas上下文报错问题