四则运算

一、摘要

  作业地址:https://edu.cnblogs.com/campus/nenu/2016CS/homework/2266

  git仓库地址:https://git.coding.net/kefei101/f4.git

  结对成员:田佳欣  https://www.cnblogs.com/tianjx687/p/9933776.html

二、需求分析

  通过对题目功能一、功能二、功能三的分析,我们共提取出以下6个需求:

  1、对输入格式的判断,以及路径、提示功能的实现;

  2、分别实现整数运算、整数小数运算;

  3、分别实现不含括号的四则运算、含括号的四则运算;

  4、对运算结果的处理分别实现保留三位小数、日常化;

  5、分别实现答题计算、输出算式结果到指定txt文件;

  6、分别实现表达式可重复的四则运算、表达式不重复的四则运算。

三、解题思路

  我们共设计了6个类,如图:

    Creat类:负责随机产生N条3个运算符,4个运算数的四则运算的式子。

    Calculator类:负责计算答案。

    MakeFile类:负责运算结果输出至控制台上,且保存到指定位置的txt文件中。

    Symbol类:负责将产生的代表运算符的数字转换成对应的运算符。

         (0:“+”;1:“-”;2:“*”;3:“/”)

    Result类:负责处理不同功能要求的输出结果格式。

    Main类:主类,负责接收控制台输入,并判断其输入格式,应实现的功能。

    6个类的相互调用关系为:

  

    比较重要的函数有:

      Main类:main():判断输入格式以及路径、提示功能的实现,主要是逻辑。

        Create类:createProblem(int n,int no):随机产生N个运算数为整数,不带括号的四则运算式子;createSm(int n):随机产生N个运算数为整数小数均可的,带有括号的四则运算式子。(n表示n个式子,no表示功能一二的选择) 

        Calculator类:algorithm(int[] var):计算运算数为整数,不带括号的式子具体计算算法;bracketsAlgo(int[] var):计算运算数整数小数均可 ,带括号的式子计提计算算法。(var[]代表将要存放的运算符)  

      MakeFile类:creatFile(int n,String filename):将N个四则运算式子输出并存放到指定文件夹。(n表示n个式子,filename表示指定txt文件路径)

      Result类:treat(double res):实现不同功能对对输出结果的要求。

四、测试运行  

  1、输入格式错误: 

  2、功能一、功能二

  3、功能三

五、重要代码展示

  1、主方法main()测试:由于有足够的前期基础,逻辑这块没有多大难度,唯一有点难度的,就是会使用库方法获取项目路径。

     /**
* Main主函数
* @param args args
*/
public static void main(String[] args){ if(args.length==0){
System.out.println("请进入小程序所在文件夹,并以正确的格式输入。");
System.exit(1); //结束运行
} else if (args.length == 2) {
if (args[0].equals("-n")) {
if (args[1].matches("^[0-9]*$")) {
int num = Integer.parseInt(args[1]);
if (num < 0) {
System.out.println("题目数量必须是 正整数。");
System.exit(1); //结束运行
}else{
Create create = new Create();
create.createProblem(num, 1);
}
} else {
System.out.println("题目数量必须是 正整数。");
System.exit(1); //结束运行
}
} else if (args[0].equals("-c")) {
if (args[1].matches("^[0-9]*$")) {
int num = Integer.parseInt(args[1]);
if (num > 100 || num < 1) {
System.out.println("题目数量范围为1到100之间的正整数。");
System.exit(1); //结束运行
}else {
Create create = new Create();
create.createProblem(num, 2);
}
} else {
System.out.println("题目数量范围为1到100之间的正整数。");
System.exit(1); //结束运行
}
} else {
System.out.println("输入格式错误!");
System.exit(1); //结束运行
}
}
//f4 -c 题目总数 -f txt文件路径
else if (args.length == 4) {
String fileName = args[3];
if (args[0].equals("-c") && args[2].equals("-f")) {
if (args[1].matches("^[0-9]*$")) {
int num = Integer.parseInt(args[1]);
if (num > 100 || num < 1) {
System.out.println("题目数量范围为1到100之间的正整数。");
System.exit(1); //结束运行
}else {
MakeFile makeFile = new MakeFile();
makeFile.creatFile(num, fileName);
}
} else {
System.out.println("题目数量范围为1到100之间的正整数。");
System.exit(1); //结束运行
}
} else {
System.out.println("输入格式错误!");
System.exit(1); //结束运行
}
} else {
System.out.println("输入格式错误!");
System.exit(1); //结束运行
}
}

main

  2、Create类中的createProblem(int n,int no)方法和createSm(int n)方法:这个两个方法中,我们认为操作数要求是整数,结果还需要四舍五入比较难处理。由于已经确定操作符和操作数个数,在其中分别根据功能的选择调用Calculator的algorithm(opNum)和bracketsAlgo(opNum)方法,将在此输入的用户答案与计算返回的答案比较,输出。总体来说,不算太难。

         //产生n个式子
for(int i=0;i<n;i++) {
calculator = new Calculator();
//初始化操作符类
for(int j=0;j<operatorCount;j++){
opNum[j]=0;
}
//随机产生式子并计算结果
if(no==1) {
equation = calculator.algorithm(opNum);
}else if(no==2){
equation = calculator.bracketsAlgo(opNum);
}
StringTokenizer stringTokenizer = new StringTokenizer(equation, "=");
ArrayList<String> list = new ArrayList<String>();
while (stringTokenizer.hasMoreElements()) {
list.add(stringTokenizer.nextToken());
}
//输出式子
System.out.println(list.get(0));
//输入
System.out.print("?");
Scanner scanner = new Scanner(System.in);
String ans = scanner.next();
//判断输入是否与正确答案相符
if(ans.equals(list.get(1))){
count++;
System.out.println("回答正确。");
}else {
System.out.println("回答错误,正确答案是" + list.get(1) + "。");
}
}

createProblem

      /**
*产生n个含括号的整数小数运算式式子
* @param n n
* @return return
*/
public ArrayList<String> createSm(int n) { ArrayList<String> list = new ArrayList<String>();//最终
ArrayList<String> list0 = new ArrayList<String>(); Calculator calculator = null;
String equation = null;
int operatorCount = 3;//3个操作符
int[] opNum = new int[operatorCount];//操作符数组
int count = 0;
int max = 0;
int[] len = new int[n];
//产生n个式子
for(int i=0;i<n;i++) {
ArrayList<String> list1 = new ArrayList<String>();
calculator = new Calculator();
//初始化操作符类
for(int j=0;j<operatorCount;j++){
opNum[j]=0;
}
//随机产生式子并计算结果
equation = calculator.bracketsAlgo(opNum);
list0.add(equation);
StringTokenizer stringTokenizer = new StringTokenizer(equation, "=");
while (stringTokenizer.hasMoreElements()) {
list1.add(stringTokenizer.nextToken());
}
//计算最长式子的长度
if(max<list1.get(0).length()) {
max=list1.get(0).length();
}
//计算每个式子的长度,存入数组,便于后续格式
len[i] = list1.get(0).length();
}
//最终正确格式
for(int i=0;i<n;i++){
ArrayList<String> list1 = new ArrayList<String>();
StringTokenizer stringTokenizer = new StringTokenizer(list0.get(i), "=");
while (stringTokenizer.hasMoreElements()) {
list1.add(stringTokenizer.nextToken());
}
String equ = list1.get(0) + "=";
//添加空格
for(int j = 0 ; j < 8 + max - len[i]; j++){
equ +=" ";
}
equ += list1.get(1);
list.add(equ);
}
return list;
}

createSm

  3、Calculator类中的algorithm(opNum)方法和bracketsAlgo(opNum):这两方法是整个四则运算程序的重中之重。由于题中操作符操作数个数给定了,功能也无需很强大,因此,我们没有采用栈来计算,而是采用最原始,于我们来说容易理解的方法进行计算。其中判断以及后期的调试花了很大功夫。

      /**
* 功能一:不带括号
* @param var var
* @return return
*/
public String algorithm(int[] var) {
Random random = new Random();
int n = var.length+1;//4个操作数
int[] num = new int[n];//4个操作数
Double[] num1 = new Double[n];//4个操作数
int[] algo = new int[n+var.length];//存放产生四则运算数组
int count = 0;//运算次数
while(count<var.length){
if(var.length == 3){
var[0]=(int)(Math.random()*4);
var[1]=(int)(Math.random()*4);
var[2]=(int)(Math.random()*4);
}
for(int i=0;i<n;i++){
num[i]=random.nextInt(20);//随机产生4个正整数,存放在num数组中
}
for(int i=0;i<n;i++){
num1[i]= Double.valueOf(num[i]);//产生的符合规定的运算符存到num1数组中
} //产生的符合规定的运算符存到m1数组中,m1数组长度比字符数量多一,方便后面运算
int m[] = new int[var.length+1];
for(int i=0;i<var.length;i++){
m[i]=var[i];
} //将运算符跟数字交错存到数组中,输出为一个四则运算
algo[0]=num[0];
algo[1]=var[0];
for(int i=2;i<n+var.length;i++){
if(i%2==0){
algo[i]=num[i/2];
}else
algo[i]=var[i/2];
} //将运算符从前到后两两比较,先计算优先级高的运算符,先乘除后加减,同级运算符从左向右依次计算
//优先级:0:+ 1:- 2:* 3:/
for(int i=0;i<var.length;i++){
//*优先,后加减
if((m[i]<m[i+1]) && (m[i+1]==2)){
num1[i+2]=num1[i+1]*num1[i+2];
num1[i+1]=num1[i];
m[i+1]=m[i];
count++;
}
//除优先,后加减
else if((m[i]<m[i+1]) && m[i+1]==3&&m[i]!=2){
if(num1[i+2]!=0.0){
BigDecimal v1 = new BigDecimal(num1[i + 1]);
BigDecimal v2 = new BigDecimal(num1[i + 2]);
Double v3 = (v1.divide(v2,4, RoundingMode.HALF_UP)).doubleValue();
num1[i+2] = v3;
num1[i + 1] = num1[i];
m[i + 1] = m[i];
count++;
}
else {//除数为0,重新进行四则运算的产生
count = 0;
for (int k = 0; k < var.length; k++) {
var[k] = 0;
}
break;
}
//先乘后除,从左至右
}else if (m[i] == 2 && m[i + 1] == 3) {
num1[i + 1] = num1[i] * num1[i + 1];
count++;
//先加后减,从左至右
} else if ((m[i] < m[i + 1]) && (m[i + 1] == 1)) {
num1[i + 1] = num1[i] + num1[i + 1];
count++;
//先除,从左至右
} else if ((m[i] > m[i + 1]) && m[i] == 3) {
BigDecimal v1 = new BigDecimal(num1[i]);
BigDecimal v2 = new BigDecimal(num1[i + 1]);
Double v3 = (v1.divide(v2,4, RoundingMode.HALF_UP)).doubleValue();
num1[i + 1] = v3;
count++;
//先乘,先加,从左至右
} else if ((m[i] > m[i + 1]) && m[i] == 2) {
num1[i + 1] = num1[i] * num1[i + 1];
count++;
//先减,从左至右
} else if ((m[i] > m[i + 1]) && m[i] == 1) {
num1[i + 1] = num1[i] - num1[i + 1];
count++;
//优先级相同
} else {
/* 包括情况为0==0;1==1;2==2 3==3*/
if (m[i] == m[i + 1]) {
if (m[i] == 0) { //加法
num1[i + 1] = num1[i] + num1[i + 1];
count++;
} else if (m[i] == 1) { //减法
num1[i + 1] = num1[i] - num1[i + 1];
count++;
} else if (m[i] == 2) { //乘法
num1[i + 1] = num1[i] * num1[i + 1];
count++;
} else { //除法运算,判断除数不能为0
if (num1[i + 2] != 0.0) {
BigDecimal v1 = new BigDecimal(num1[i]);
BigDecimal v2 = new BigDecimal(num1[i + 1]);
Double v3 = (v1.divide(v2, 4, RoundingMode.HALF_UP)).doubleValue();
num1[i + 1] = v3;
count++;
} else {//除数为0,重新进行四则运算的产生
count = 0;
for (int k = 0; k < var.length; k++) {
var[k] = 0;
}
break;
}
}
}
}
}
}
//将符合要求的四则运算从数组中输出 ,如果为运算符,调用Symbol类中算法symbol函数,将数字转化为运算符输出
Symbol sym =new Symbol();
String S;
S = String.valueOf(algo[0]) + sym.symbol(algo[1]);
sym.symbol(algo[1]);
for (int j = 2; j < algo.length; j++) {
if (j % 2 == 0)
S = S + String.valueOf(algo[j]);
else {
S = S + sym.symbol(algo[j]);
}
}
Result result = new Result();
String dou = result.treat(num1[num1.length - 1]);
S = S + "=" + dou;//输出运算结果
return S;
}

algorithm

  这个算法最主要的是运算符之间优先级的比较。

  (1)将运算符从前到后两两比较,先计算优先级高的运算符,先乘除后加减,同级运算符从左向右依次计算。

  (2)通过运算符两两比较,每循环一次将生成的结果替代原来的数字,循环结束后,最终的结果会放到数组的最后一位。若除法时,除数为0,则重新开始。

     /**
* 功能二、功能三:带括号,运算数可带小数
* @param var var
* @return return
*/
public String bracketsAlgo(int[] var) {
Result result = new Result();
Random random = new Random();
//随机产生运算符
if (var.length == 3) {
var[0] = (int) (Math.random() * 4);
var[1] = (int) (Math.random() * 4);
var[2] = (int) (Math.random() * 4);
} //随机生成的运算符从左向右两两比较
double f1 = random.nextDouble()*random.nextInt(20);//随机产生4个正数,存放在num数组中
double f2 = random.nextDouble()*random.nextInt(20);
BigDecimal n1 = new BigDecimal(f1);
BigDecimal n2 = new BigDecimal(f2);
f1 = n1.setScale(1,BigDecimal.ROUND_HALF_UP).doubleValue();
f2 = n2.setScale(1,BigDecimal.ROUND_HALF_UP).doubleValue();
String str = "";//算式
double st = 0;//当前结果 if(var[0]==0){
st = f1+f2;
str = result.treat(f1) + "+" + result.treat(f2);
}else if(var[0]==1){
st = f1-f2;
str = result.treat(f1) + "-" + result.treat(f2);
}else if(var[0]==2){
st = f1*f2;
str = result.treat(f1) + "*" + result.treat(f2);
}else{
while(f2==0){
f2 = random.nextDouble()*random.nextInt(20);
}
BigDecimal v1 = new BigDecimal(f1);
BigDecimal v2 = new BigDecimal(f2);
Double v3 = (v1.divide(v2, 4, RoundingMode.HALF_UP)).doubleValue();
st=v3;
str = result.treat(f1) + "/" + result.treat(f2);
} for(int i=1;i<var.length;++i){
f1 = random.nextDouble()*random.nextInt(20);
BigDecimal n3 = new BigDecimal(f1);
f1 = n3.setScale(1,BigDecimal.ROUND_HALF_UP).doubleValue();
if(priority(var[i-1])<priority(var[i])){
if(var[i]!=3){
st *= f1;
str = "(" + str + ")*" + result.treat(f1);
}else{
while(f1==0){
f1 = random.nextDouble()*random.nextInt(20);
}
BigDecimal v1 = new BigDecimal(st);
BigDecimal v2 = new BigDecimal(f1);
Double v3 = (v1.divide(v2, 4, RoundingMode.HALF_UP)).doubleValue();
st=v3;
str = "(" + str + ")/" + result.treat(f1);
}
}else if(var[i]==0){
st += f1;
str = str + "+" + result.treat(f1);
}else if(var[i]==1){
if(var[i - 1] == 1) {
st = f1 - st;
str = result.treat(f1) + "-(" + str + ")";
}else{
st -= f1;
str = str + "-" + result.treat(f1);
}
}else if(var[i] == 2) {
st *= f1;
str = str + "*" + result.treat(f1);
}else{
while(f1==0){
f1 = random.nextDouble()*random.nextInt(20);
}
BigDecimal v1 = new BigDecimal(st);
BigDecimal v2 = new BigDecimal(f1);
Double v3 = (v1.divide(v2, 4, RoundingMode.HALF_UP)).doubleValue();
st=v3;
str = str + "/" + result.treat(f1);
}
}
str = str + "=";//输出运算结果
String cou = result.treat(st);
str +=cou;
return str;
}

bracketsAlgo

  这个算法也是主要比较运算符的优先级。将随机生成的运算符从左向右两两比较,如果前者优先级高,则先计算保存结果,如果前者优先级低,则加上括号。这样也是优缺点的,这种算法只能从左向右运算,无法实现更为精致的随机生成。后期我也会继续关注这算法,以求改进。

  4、MakeFile类中的creatFile(int n,String filename)方法:由于底层的随机生成算式的算法已经实现了,这个方法主要是文件的创建及算式的写入。这个不会太难。

     /**
* 实现将算式写入指定txt文件
* @param n n
* @param fileName fileName
*/
public void creatFile(int n,String fileName){
try{
File file = new File(fileName);
if (file.exists()) { //如果文件已存在,则删除文件
file.delete();
}
if(file.createNewFile()){
FileOutputStream txtFile = new FileOutputStream(file);
PrintStream p = new PrintStream(txtFile);
ArrayList<String> list = new ArrayList<String>();
Create create = new Create();
list = create.createSm(n);
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
p.println(list.get(i));
}
txtFile.close();
p.close();
}
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}

creatFile

  5、Result类的treat(double res)方法:这个方法我们是用来处理功能一功能二不同的输出要求的。同时针对题目中提到的“例如2/3-1/3的正确结果是0.333,而并非0.334”,我想到了题目中要求保留3位小数,那我们可以保留四位小数,在处理过程中再四舍五入,其结果无差。

      /**
* 处理输出结果
* @param res res
* @return return
*/
public static String treat(double res) {
BigDecimal b = new BigDecimal(res);
res = b.setScale(3,BigDecimal.ROUND_HALF_UP).doubleValue();
int aInt = (int)res;
String bDou = res+"";
String bDou1 = bDou.substring(bDou.indexOf(".")+1,bDou.length());
if(bDou1.equals("0")){
return String.valueOf(aInt);
}
else{
return String.valueOf(res);
}
}

treat

六、编程体会、收获事件

  1、体会

    在软件工程这门课中,到目前为止已经写了4次作业了。每一次写作业都会让我受益多多。我也发现自己做作业的效率一次比一次高,学习能力明显增强了,这是值得开心的事情。那对于这次作业呢,首先我觉得它是比上次wf词频统计小程序的作业难上加难,所涉及到的算法高度也不同,虽然这是结对项目,但在一起编代码的过程中也凸显了一点问题,比如说俩人意见不一,凑在一起编程的时间不多等等,在编程过程中还是有些费力的,尤其是在编写判断逻辑和后期调试花了太多的功夫。希望自己在接下来的软件工程课程上学到更多东西,在算法下功夫,不断提高编程能力,靠近预期目标。

  2、事件

    (1)首先我们在项目的构造上花费了2天时间,思考讨论的结果,参照我上次wf词频统计小程序的思路,一层一层逐步深入,先构造好大体逻辑结构,哪块是什么功能,再逐步细化。

    (2)其次我们卡在功能一花费了3天时间,功能一实际上也是功能二和功能三的基础。式子用什么表达,怎么计算,怎么产生正确的无限长小数运算的四舍五入等等都是要有方案解决的。网上资料虽然很多,但要做到符合要求基本是没有的,而且我们想真正用我们自己想的方法把这些问题解决,真正地编程学习。

    (3)最后,我们还卡在了一个非常尴尬的点上。题中要求写一个控制台程序,一开始我们以为是在控制台输入,使用scanner获取用户输入参数。但后来经过舍友提醒,又让我想起上次冉华学长对我说的话,就再去查查控制台程序输入,应该用命令行参数输入格式。可是我们试了好久,控制台直接闪退,显示输入格式错误,不知道哪里出问题,还一度怀疑是IDEA的锅。将近半天,才发现输入格式的f4不作为判断条件,它不是命令行参数中的一个。真是天大又无语的乌龙啊— —!

软件工程 week 04的更多相关文章

  1. [软件工程基础]2017.11.04 第八次 Scrum 会议

    具体事项 项目交接燃尽图 每人工作内容 成员 已完成的工作 计划完成的工作 工作中遇到的困难 游心 #10 搭建可用的开发测试环境:#9 阅读分析 PhyLab 后端代码与文档:#8 掌握 Larav ...

  2. 现代软件工程 第十六章 【IT 行业的创新】练习与讨论

    16.6.0  Xerox Parc 的成功创新和推向市场的失败 http://research.microsoft.com/en-us/um/people/blampson/Slides/AltoA ...

  3. 软件工程练习:模块化,单元测试,回归测试,TDD

    这是<构建之法>实战教学的一部分.适合作为同学们的第二个程序作业. 第一个程序作业: 请看 “概论” 一章的练习,或者老师的题目,例如这个. 作业要求: 软件工程的作业越来越有意思了, 我 ...

  4. BUAA_2020_软件工程_个人项目作业

    作业抬头(1') 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人项目作业 我在这个课程的目标是 了解软件工程的技术,掌握工程化开发的能力 这 ...

  5. Python学习--04条件控制与循环结构

    Python学习--04条件控制与循环结构 条件控制 在Python程序中,用if语句实现条件控制. 语法格式: if <条件判断1>: <执行1> elif <条件判断 ...

  6. Ubuntu 14.04中Elasticsearch集群配置

    Ubuntu 14.04中Elasticsearch集群配置 前言:本文可用于elasticsearch集群搭建参考.细分为elasticsearch.yml配置和系统配置 达到的目的:各台机器配置成 ...

  7. win8.1硬盘安装ubuntu14.04双系统

    在网上找了很多方法都失败了,原因是大多数方法都是用mbr方式安装的,如grub4dos,easybcd.以至于连自己都怀疑win8能不能用硬盘安装,差点就去买个u盘来安装了,就在打算放弃的时候在ubu ...

  8. 软件工程(C编码实践篇)学习心得

    孟繁琛 + 原创作品转载请注明出处 + <软件工程(C编码实践篇)>MOOC课程 http://mooc.study.163.com/course/USTC-1000002006 软件工程 ...

  9. 敏捷软件开发VS传统软件工程

    敏捷软件开发:又称敏捷开发,是一种从1990年代开始逐渐引起广泛关注的一些新兴软件开发方法,是一种应对快速变化的需求的一种软件开发能力. 与传统软件工程相比,它们的具体名称.理念.过程.术语都不尽相同 ...

随机推荐

  1. 【Bilinear interpolation】双线性插值详解(转)

           最近在做视频拼接的项目,里面用到了图像的单应性矩阵变换,在最后的图像重映射,由于目标图像的坐标是非整数的,所以需要用到插值的方法,用的就是双线性插值,下面的博文主要是查看了前辈的博客对双 ...

  2. 命令行找不到genstrings问题tip

    问题:初次使用命令行genstrings,提示使用的是命令行工具而非xcode,无法直接使用genstrings. 解决方案:命令行输入sudo xcode-select --switch /Appl ...

  3. QuerySet API

    模型objects:这个对象是 django.db.model.manager.Manger 的对象,这个类是一个空壳类,它上面的所有方法都是从 QuerySet 这个类中拷贝过来的. >> ...

  4. Codeforces Round #495 (Div. 2) C. Sonya and Robots

    http://codeforces.com/contest/1004/problem/C 题意: 在一行上有n个数字,现在在最左边和最右边各放置一个机器人,左右机器人各有一个数字p和q.现在这两个机器 ...

  5. scp免密操作

    scp免密操作 2.1服务器(本机)从目标服务器上传/下载文件或者文件夹 2.2生成秘钥 本机执行:ssh-keygen -t rsa 遇到提示,直接回车就OK,秘钥生成在用户的根目录的.ssh目录下 ...

  6. h5设计图尺寸

    640 标准的话 设计图: 640*1136 body,html 背景图的话需要640*1008的 这样才能整屏刚刚好 750 标准的话 设计图: 750*1334 body,html背景图的话,75 ...

  7. 函数式语言简介(functional language)

    1.什么是函数式语言?        是一种非冯·诺伊曼式的程序设计语言.函数式语言主要成分是原始函数.定义函数和函数型.这种语言具有较强的组织数据结构的能力,可以把某一数据结构(如数组)作为单一值处 ...

  8. 雷林鹏分享:jQuery EasyUI 数据网格 - 启用行内编辑

    jQuery EasyUI 数据网格 - 启用行内编辑 可编辑的功能是最近添加到数据网格(datagrid)的.它可以使用户添加一个新行到数据网格(datagrid).用户也可以更新一个或多个行. 本 ...

  9. hdoj5754

    题意:略 国王和骑士用记忆搜索,注意骑士的移动是x-2,y-1或x-1,y-2.车是NIM博弈,后是威佐夫博弈.注意威佐夫博弈中两堆石子有大小之分,而输入不一定小在前. #include <io ...

  10. 『PyTorch』第五弹_深入理解Tensor对象_中下:数学计算以及numpy比较_&_广播原理简介

    一.简单数学操作 1.逐元素操作 t.clamp(a,min=2,max=4)近似于tf.clip_by_value(A, min, max),修剪值域. a = t.arange(0,6).view ...