精华内容
下载资源
问答
  • java去除sql查询字段左右的空格发布时间:2019-01-30 09:26,浏览次数:414, 标签:java去空格String a ="((booktime >= '2019-01-29 11:10:59' and booktime <= '2019-01-29 23:59:59') AND billno = ' 111 ' ...

    java去除sql查询字段左右的空格

    发布时间:2019-01-30 09:26,

    浏览次数:414

    , 标签:

    java

    去空格

    String a ="((booktime >= '2019-01-29 11:10:59' and booktime <= '2019-01-29 23:59:59') AND billno = '  111 ' AND soid = '11122') and isnull(dr, 0)=0 and processstatus <>-2 and processstatus <>'-1' and processstatus <>'0'  and esoc_order.pk_group='0001A210000000000K2M' and esoc_order.pk_org in ('0001A210000000000CCT')";

    String[] strArr = a.split("'");

    StringBuffer b=new StringBuffer();

    for(int i=0;i

    String str = strArr[i];

    System.out.println(str);

    if((i&1) != 1){//是偶数

    b.append(str).append("'");//不去空格

    }else{

    b.append(str.trim()).append("'");//去空格

    }

    }

    String newSqlWhere = b.toString();

    if(newSqlWhere.length()>0){

    newSqlWhere=newSqlWhere.substring(0, newSqlWhere.length()-1);

    }

    if(a.equals(newSqlWhere)){

    System.out.println("相等");

    }else{

    System.out.println("不等");

    System.out.println(newSqlWhere);

    }

    展开全文
  • 1)的整型数组A,可以将A划分成左右两个部分,左部分A[0…K],右部分A[K+1…N-1],K可以取值的范围是[0,N-2]。求这么多划分方案中,左部分中的最大值减去右部分最大值的绝对值,最大是多少? 给定整数数组A和数组的...

    题目

    给定一个长度为N(N>1)的整型数组A,可以将A划分成左右两个部分,左部分A[0…K],右部分A[K+1…N-1],K可以取值的范围是[0,N-2]。求这么多划分方案中,左部分中的最大值减去右部分最大值的绝对值,最大是多少?

    给定整数数组A和数组的大小n,请返回题目所求的答案。

    测试样例:

    [2,7,3,1,1],5

    返回:6

    分析

    仔细审题,可以发现数组中的最大数无论分在左边还是右边,都会是这一边的最大数,
    而为了使两边的差值最大,就必须使另一边的最大数尽可能的小,而每一边都至少会有一个数,即数组的第一个数或者最后一个数,那么另一边的最大数最小只能是这个必须要有的数,因为如果含有其他数的话,只会使最大数变大,而不会变小。

    代码

    public class MaxGap {
        public int findMaxGap(int[] A, int n) {
            // write code here
    		int max = Integer.MIN_VALUE;
            for (int i = 0; i < A.length; i++) {
                if (max < A[i]) max = A[i];
            }
            return max - Math.min(A[0], A[n - 1]);
        }
    }
    
    展开全文
  • Java集合详解8:Java集合类细节精讲

    千次阅读 2018-05-13 10:25:12
    今天我们来探索一下Java集合类中的一些技术细节。主要是对一些比较容易被遗漏和误解的知识点做一些讲解和补充。可能不全面,还请谅解。 本文参考:http://cmsblogs.com/?cat=5 具体代码在我的GitHub中可以找到 ...

    《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始写的新系列。

    这些文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看

    https://github.com/h2pl/Java-Tutorial

    喜欢的话麻烦点下Star、fork哈

    文章首发于我的个人博客:

    www.how2playlife.com

    今天我们来探索一下Java集合类中的一些技术细节。主要是对一些比较容易被遗漏和误解的知识点做一些讲解和补充。可能不全面,还请谅解。

    初始容量

    集合是我们在Java编程中使用非常广泛的,它就像大海,海纳百川,像万能容器,盛装万物,而且这个大海,万能容器还可以无限变大(如果条件允许)。当这个海、容器的量变得非常大的时候,它的初始容量就会显得很重要了,因为挖海、扩容是需要消耗大量的人力物力财力的。

    同样的道理,Collection的初始容量也显得异常重要。所以:对于已知的情景,请为集合指定初始容量。

    public static void main(String[] args) {
        StudentVO student = null;
        long begin1 = System.currentTimeMillis();
        List<StudentVO> list1 = new ArrayList<>();
        for(int i = 0 ; i < 1000000; i++){
            student = new StudentVO(i,"chenssy_"+i,i);
            list1.add(student);
        }
        long end1 = System.currentTimeMillis();
        System.out.println("list1 time:" + (end1 - begin1));
        
        long begin2 = System.currentTimeMillis();
        List<StudentVO> list2 = new ArrayList<>(1000000);
        for(int i = 0 ; i < 1000000; i++){
            student = new StudentVO(i,"chenssy_"+i,i);
            list2.add(student);
        }
        long end2 = System.currentTimeMillis();
        System.out.println("list2 time:" + (end2 - begin2));
    }
    

    上面代码两个list都是插入1000000条数据,只不过list1没有没有申请初始化容量,而list2初始化容量1000000。那运行结果如下:

    list1 time:1638
    list2 time:921
    

    从上面的运行结果我们可以看出list2的速度是list1的两倍左右。在前面LZ就提过,ArrayList的扩容机制是比较消耗资源的。我们先看ArrayList的add方法:

    public boolean add(E e) {  
            ensureCapacity(size + 1);   
            elementData[size++] = e;  
            return true;  
        }  
    
    public void ensureCapacity(int minCapacity) {  
        modCount++;         //修改计数器
        int oldCapacity = elementData.length;    
        //当前需要的长度超过了数组长度,进行扩容处理
        if (minCapacity > oldCapacity) {  
            Object oldData[] = elementData;  
            //新的容量 = 旧容量 * 1.5 + 1
            int newCapacity = (oldCapacity * 3)/2 + 1;  
                if (newCapacity < minCapacity)  
                    newCapacity = minCapacity;  
          //数组拷贝,生成新的数组 
          elementData = Arrays.copyOf(elementData, newCapacity);  
        }  
    }
    

    ArrayList每次新增一个元素,就会检测ArrayList的当前容量是否已经到达临界点,如果到达临界点则会扩容1.5倍。然而ArrayList的扩容以及数组的拷贝生成新的数组是相当耗资源的。所以若我们事先已知集合的使用场景,知道集合的大概范围,我们最好是指定初始化容量,这样对资源的利用会更加好,尤其是大数据量的前提下,效率的提升和资源的利用会显得更加具有优势。

    asList的缺陷

    在实际开发过程中我们经常使用asList讲数组转换为List,这个方法使用起来非常方便,但是asList方法存在几个缺陷:

    避免使用基本数据类型数组转换为列表

    使用8个基本类型数组转换为列表时会存在一个比较有味的缺陷。先看如下程序:

    public static void main(String[] args) {
            int[] ints = {1,2,3,4,5};
            List list = Arrays.asList(ints);
            System.out.println("list'size:" + list.size());
        }
    ------------------------------------
    outPut:
    list'size:1
    

    程序的运行结果并没有像我们预期的那样是5而是逆天的1,这是什么情况?先看源码:

    public static <T> List<T> asList(T... a) {
            return new ArrayList<>(a);
        }
    

    asList接受的参数是一个泛型的变长参数,我们知道基本数据类型是无法发型化的,也就是说8个基本类型是无法作为asList的参数的, 要想作为泛型参数就必须使用其所对应的包装类型。但是这个这个实例中为什么没有出错呢?

    因为该实例是将int类型的数组当做其参数,而在Java中数组是一个对象,它是可以泛型化的。所以该例子是不会产生错误的。既然例子是将整个int类型的数组当做泛型参数,那么经过asList转换就只有一个int 的列表了。如下:

    public static void main(String[] args) {
        int[] ints = {1,2,3,4,5};
        List list = Arrays.asList(ints);
        System.out.println("list 的类型:" + list.get(0).getClass());
        System.out.println("list.get(0) == ints:" + list.get(0).equals(ints));
    }
    

    outPut:
    list 的类型:class [I
    list.get(0) == ints:true
    从这个运行结果我们可以充分证明list里面的元素就是int数组。弄清楚这点了,那么修改方法也就一目了然了:将int 改变为Integer。

    public static void main(String[] args) {
            Integer[] ints = {1,2,3,4,5};
            List list = Arrays.asList(ints);
            System.out.println("list'size:" + list.size());
            System.out.println("list.get(0) 的类型:" + list.get(0).getClass());
            System.out.println("list.get(0) == ints[0]:" + list.get(0).equals(ints[0]));
        }
    ----------------------------------------
    outPut:
    list'size:5
    list.get(0) 的类型:class java.lang.Integer
    list.get(0) == ints[0]:true
    

    asList产生的列表不可操作

    对于上面的实例我们再做一个小小的修改:

    public static void main(String[] args) {
            Integer[] ints = {1,2,3,4,5};
            List list = Arrays.asList(ints);
            list.add(6);
        }
    

    该实例就是讲ints通过asList转换为list 类别,然后再通过add方法加一个元素,这个实例简单的不能再简单了,但是运行结果呢?打出我们所料:

    Exception in thread "main" java.lang.UnsupportedOperationException
        at java.util.AbstractList.add(Unknown Source)
        at java.util.AbstractList.add(Unknown Source)
        at com.chenssy.test.arrayList.AsListTest.main(AsListTest.java:10)
    

    运行结果尽然抛出UnsupportedOperationException异常,该异常表示list不支持add方法。这就让我们郁闷了,list怎么可能不支持add方法呢?难道jdk脑袋堵塞了?我们再看asList的源码:

    public static <T> List<T> asList(T... a) {
            return new ArrayList<>(a);
        }
    

    asList接受参数后,直接new 一个ArrayList,到这里看应该是没有错误的啊?别急,再往下看:

    private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable{
            private static final long serialVersionUID = -2764017481108945198L;
            private final E[] a;
    
            ArrayList(E[] array) {
                if (array==null)
                    throw new NullPointerException();
                a = array;
            }
            //.................
        }
    

    这是ArrayList的源码,从这里我们可以看出,此ArrayList不是java.util.ArrayList,他是Arrays的内部类。

    该内部类提供了size、toArray、get、set、indexOf、contains方法,而像add、remove等改变list结果的方法从AbstractList父类继承过来,同时这些方法也比较奇葩,它直接抛出UnsupportedOperationException异常:

    public boolean add(E e) {
            add(size(), e);
            return true;
        }
        
        public E set(int index, E element) {
            throw new UnsupportedOperationException();
        }
        
        public void add(int index, E element) {
            throw new UnsupportedOperationException();
        }
        
        public E remove(int index) {
            throw new UnsupportedOperationException();
        }
    

    通过这些代码可以看出asList返回的列表只不过是一个披着list的外衣,它并没有list的基本特性(变长)。该list是一个长度不可变的列表,传入参数的数组有多长,其返回的列表就只能是多长。所以::不要试图改变asList返回的列表,否则你会自食苦果。

    subList的缺陷

    我们经常使用subString方法来对String对象进行分割处理,同时我们也可以使用subList、subMap、subSet来对List、Map、Set进行分割处理,但是这个分割存在某些瑕疵。

    subList返回仅仅只是一个视图

    首先我们先看如下实例:

    public static void main(String[] args) {
    List list1 = new ArrayList();
    list1.add(1);
    list1.add(2);

        //通过构造函数新建一个包含list1的列表 list2
        List<Integer> list2 = new ArrayList<Integer>(list1);
        
        //通过subList生成一个与list1一样的列表 list3
        List<Integer> list3 = list1.subList(0, list1.size());
        
        //修改list3
        list3.add(3);
        
        System.out.println("list1 == list2:" + list1.equals(list2));
        System.out.println("list1 == list3:" + list1.equals(list3));
    }
    

    这个例子非常简单,无非就是通过构造函数、subList重新生成一个与list1一样的list,然后修改list3,最后比较list1 == list2?、list1 == list3?。

    按照我们常规的思路应该是这样的:因为list3通过add新增了一个元素,那么它肯定与list1不等,而list2是通过list1构造出来的,所以应该相等,所以结果应该是:

    list1 == list2:true
    list1 == list3: false
    

    首先我们先不论结果的正确与否,我们先看subList的源码:

    public List<E> subList(int fromIndex, int toIndex) {
            subListRangeCheck(fromIndex, toIndex, size);
            return new SubList(this, 0, fromIndex, toIndex);
    }
    

    subListRangeCheck方式是判断fromIndex、toIndex是否合法,如果合法就直接返回一个subList对象,注意在产生该new该对象的时候传递了一个参数 this ,该参数非常重要,因为他代表着原始list。

    /**
    * 继承AbstractList类,实现RandomAccess接口
    */
    private class SubList extends AbstractList implements RandomAccess {
    private final AbstractList parent; //列表
    private final int parentOffset;
    private final int offset;
    int size;

        //构造函数
        SubList(AbstractList<E> parent,
                int offset, int fromIndex, int toIndex) {
            this.parent = parent;
            this.parentOffset = fromIndex;
            this.offset = offset + fromIndex;
            this.size = toIndex - fromIndex;
            this.modCount = ArrayList.this.modCount;
        }
    
        //set方法
        public E set(int index, E e) {
            rangeCheck(index);
            checkForComodification();
            E oldValue = ArrayList.this.elementData(offset + index);
            ArrayList.this.elementData[offset + index] = e;
            return oldValue;
        }
    
        //get方法
        public E get(int index) {
            rangeCheck(index);
            checkForComodification();
            return ArrayList.this.elementData(offset + index);
        }
    
        //add方法
        public void add(int index, E e) {
            rangeCheckForAdd(index);
            checkForComodification();
            parent.add(parentOffset + index, e);
            this.modCount = parent.modCount;
            this.size++;
        }
    
        //remove方法
        public E remove(int index) {
            rangeCheck(index);
            checkForComodification();
            E result = parent.remove(parentOffset + index);
            this.modCount = parent.modCount;
            this.size--;
            return result;
        }
    }
    

    该SubLsit是ArrayList的内部类,它与ArrayList一样,都是继承AbstractList和实现RandomAccess接口。同时也提供了get、set、add、remove等list常用的方法。但是它的构造函数有点特殊,在该构造函数中有两个地方需要注意:

    1、this.parent = parent;而parent就是在前面传递过来的list,也就是说this.parent就是原始list的引用。

    2、this.offset = offset + fromIndex;this.parentOffset = fromIndex;。同时在构造函数中它甚至将modCount(fail-fast机制)传递过来了。

    我们再看get方法,在get方法中return ArrayList.this.elementData(offset + index);

    这段代码可以清晰表明get所返回就是原列表offset + index位置的元素。同样的道理还有add方法里面的:

    parent.add(parentOffset + index, e);
    this.modCount = parent.modCount;
    remove方法里面的

    E result = parent.remove(parentOffset + index);
    this.modCount = parent.modCount;

    诚然,到了这里我们可以判断subList返回的SubList同样也是AbstractList的子类,同时它的方法如get、set、add、remove等都是在原列表上面做操作,它并没有像subString一样生成一个新的对象。

    所以subList返回的只是原列表的一个视图,它所有的操作最终都会作用在原列表上。

    那么从这里的分析我们可以得出上面的结果应该恰恰与我们上面的答案相反:

    list1 == list2:false
    list1 == list3:true

    subList生成子列表后,不要试图去操作原列表

    从上面我们知道subList生成的子列表只是原列表的一个视图而已,如果我们操作子列表它产生的作用都会在原列表上面表现,但是如果我们操作原列表会产生什么情况呢?

    public static void main(String[] args) {
    List list1 = new ArrayList();
    list1.add(1);
    list1.add(2);

        //通过subList生成一个与list1一样的列表 list3
        List<Integer> list3 = list1.subList(0, list1.size());
        //修改list1
        list1.add(3);
        
        System.out.println("list1'size:" + list1.size());
        System.out.println("list3'size:" + list3.size());
    }
    

    该实例如果不产生意外,那么他们两个list的大小都应该都是3,但是偏偏事与愿违,事实上我们得到的结果是这样的:

    list1'size:3
    Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.ArrayList$SubList.checkForComodification(Unknown Source)
        at java.util.ArrayList$SubList.size(Unknown Source)
        at com.chenssy.test.arrayList.SubListTest.main(SubListTest.java:17)
    

    list1正常输出,但是list3就抛出ConcurrentModificationException异常,看过我另一篇博客的同仁肯定对这个异常非常,fail-fast?不错就是fail-fast机制,在fail-fast机制中,LZ花了很多力气来讲述这个异常,所以这里LZ就不对这个异常多讲了。我们再看size方法:

    public int size() {
                checkForComodification();
                return this.size;
            }
    

    size方法首先会通过checkForComodification验证,然后再返回this.size。

    private void checkForComodification() {
                if (ArrayList.this.modCount != this.modCount)
                    throw new ConcurrentModificationException();
            }
    

    该方法表明当原列表的modCount与this.modCount不相等时就会抛出ConcurrentModificationException。

    同时我们知道modCount 在new的过程中 "继承"了原列表modCount,只有在修改该列表(子列表)时才会修改该值(先表现在原列表后作用于子列表)。

    而在该实例中我们是操作原列表,原列表的modCount当然不会反应在子列表的modCount上啦,所以才会抛出该异常。

    对于子列表视图,它是动态生成的,生成之后就不要操作原列表了,否则必然都导致视图的不稳定而抛出异常。最好的办法就是将原列表设置为只读状态,要操作就操作子列表:

    //通过subList生成一个与list1一样的列表 list3

    List<Integer> list3 = list1.subList(0, list1.size());
    

    //对list1设置为只读状态

    list1 = Collections.unmodifiableList(list1);
    

    推荐使用subList处理局部列表

    在开发过程中我们一定会遇到这样一个问题:获取一堆数据后,需要删除某段数据。例如,有一个列表存在1000条记录,我们需要删除100-200位置处的数据,可能我们会这样处理:

    for(int i = 0 ; i < list1.size() ; i++){
       if(i >= 100 && i <= 200){
           list1.remove(i);
           /*
            * 当然这段代码存在问题,list remove之后后面的元素会填充上来,
             * 所以需要对i进行简单的处理,当然这个不是这里讨论的问题。
             */
       }
    }
    

    这个应该是我们大部分人的处理方式吧,其实还有更好的方法,利用subList。在前面LZ已经讲过,子列表的操作都会反映在原列表上。所以下面一行代码全部搞定:

    list1.subList(100, 200).clear();
    

    简单而不失华丽!!!!!

    保持compareTo和equals同步

    在Java中我们常使用Comparable接口来实现排序,其中compareTo是实现该接口方法。我们知道compareTo返回0表示两个对象相等,返回正数表示大于,返回负数表示小于。同时我们也知道equals也可以判断两个对象是否相等,那么他们两者之间是否存在关联关系呢?

    public class Student implements Comparable<Student>{
        private String id;
        private String name;
        private int age;
        
        public Student(String id,String name,int age){
            this.id = id;
            this.name = name;
            this.age = age;
        }
    
        public boolean equals(Object obj){
            if(obj == null){
                return false;
            }
            
            if(this == obj){
                return true;
            }
            
            if(obj.getClass() != this.getClass()){
                return false;
            }
            
            Student student = (Student)obj;
            if(!student.getName().equals(getName())){
                return false;
            }
            
            return true;
        }
        
        public int compareTo(Student student) {
            return this.age - student.age;
        }
    
        /** 省略getter、setter方法 */
    }
    

    Student类实现Comparable接口和实现equals方法,其中compareTo是根据age来比对的,equals是根据name来比对的。

    public static void main(String[] args){
            List<Student> list = new ArrayList<>();
            list.add(new Student("1", "chenssy1", 24));
            list.add(new Student("2", "chenssy1", 26));
            
            Collections.sort(list);   //排序
            
            Student student = new Student("2", "chenssy1", 26);
            
            //检索student在list中的位置
            int index1 = list.indexOf(student);
            int index2 = Collections.binarySearch(list, student);
            
            System.out.println("index1 = " + index1);
            System.out.println("index2 = " + index2);
        }
    

    按照常规思路来说应该两者index是一致的,因为他们检索的是同一个对象,但是非常遗憾,其运行结果:

    index1 = 0
    index2 = 1

    为什么会产生这样不同的结果呢?这是因为indexOf和binarySearch的实现机制不同。

    indexOf是基于equals来实现的只要equals返回TRUE就认为已经找到了相同的元素。

    而binarySearch是基于compareTo方法的,当compareTo返回0 时就认为已经找到了该元素。

    在我们实现的Student类中我们覆写了compareTo和equals方法,但是我们的compareTo、equals的比较依据不同,一个是基于age、一个是基于name。

    比较依据不同那么得到的结果很有可能会不同。所以知道了原因,我们就好修改了:将两者之间的比较依据保持一致即可。

    对于compareTo和equals两个方法我们可以总结为:compareTo是判断元素在排序中的位置是否相等,equals是判断元素是否相等,既然一个决定排序位置,一个决定相等,所以我们非常有必要确保当排序位置相同时,其equals也应该相等。

    使其相等的方式就是两者应该依附于相同的条件。当compareto相等时equals也应该相等,而compareto不相等时equals不应该相等,并且compareto依据某些属性来决定排序。

    参考文章

    https://www.cnblogs.com/galibujianbusana/p/6600226.html

    http://blog.itpub.net/69906029/viewspace-2641300/

    https://www.cnblogs.com/itxiaok/p/10356553.html

    微信公众号

    Java技术江湖

    如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号【Java技术江湖】一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM、SpringBoot、MySQL、分布式、中间件、集群、Linux、网络、多线程,偶尔讲点Docker、ELK,同时也分享技术干货和学习经验,致力于Java全栈开发!

    Java工程师必备学习资源: 一些Java工程师常用学习资源,关注公众号后,后台回复关键字 “Java” 即可免费无套路获取。

    我的公众号

    个人公众号:程序员黄小斜

    作者是 985 硕士,蚂蚁金服 JAVA 工程师,专注于 JAVA 后端技术栈:SpringBoot、MySQL、分布式、中间件、微服务,同时也懂点投资理财,偶尔讲点算法和计算机理论基础,坚持学习和写作,相信终身学习的力量!

    程序员3T技术学习资源: 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 “资料” 即可免费无套路获取。

    展开全文
  • Java实现四则运算

    2021-03-06 00:58:15
    程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。例如,23 + 45 = 和45 + 23 = 是重复的题目,6 × 8 = 和8 × 6 = 也是重复的题目。3+(2+1)和1+2+3...

    GitHub:https://github.com/Wamelon/operations

    组员:黄锐斌,张正浩

    1题目:实现一个自动生成小学四则运算题目的命令行程序。

    2说明:

    自然数:0, 1, 2, …。

    真分数:1/2, 1/3, 2/3, 1/4, 1’1/2, …。

    运算符:+, −, ×, ÷。

    括号:(, )。

    等号:=。

    分隔符:空格(用于四则运算符和等号前后)。

    算术表达式:

    e = n | e1 + e2 | e1 − e2 | e1 × e2 | e1 ÷ e2 | (e),

    其中e, e1和e2为表达式,n为自然数或真分数。

    四则运算题目:e = ,其中e为算术表达式。

    3需求:

    1. 使用 -n 参数控制生成题目的个数,例如

    Myapp.exe -n 10

    将生成10个题目。

    2. 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围,例如

    Myapp.exe -r 10

    将生成10以内(不包括10)的四则运算题目。该参数可以设置为1或其他自然数。该参数必须给定,否则程序报错并给出帮助信息。

    3. 生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1 − e2的子表达式,那么e1 ≥ e2。

    4. 生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数。

    5.每道题目中出现的运算符个数不超过3个。

    6. 程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。例如,23 + 45 = 和45 + 23 = 是重复的题目,6 × 8 = 和8 × 6 = 也是重复的题目。3+(2+1)和1+2+3这两个题目是重复的,由于+是左结合的,1+2+3等价于(1+2)+3,也就是3+(1+2),也就是3+(2+1)。但是1+2+3和3+2+1是不重复的两道题,因为1+2+3等价于(1+2)+3,而3+2+1等价于(3+2)+1,它们之间不能通过有限次交换变成同一个题目。

    生成的题目存入执行程序的当前目录下的Exercises.txt文件,格式如下:

    1. 四则运算题目1

    2. 四则运算题目2

    ……

    其中真分数在输入输出时采用如下格式,真分数五分之三表示为3/5,真分数二又八分之三表示为2’3/8。

    7. 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件,格式如下:

    1. 答案1

    2. 答案2

    特别的,真分数的运算如下例所示:1/6 + 1/8 = 7/24。

    8. 程序应能支持一万道题目的生成。

    9. 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计,输入参数如下:

    Myapp.exe -e .txt -a .txt

    统计结果输出到文件Grade.txt,格式如下:

    Correct: 5 (1, 3, 5, 7, 9)

    Wrong: 5 (2, 4, 6, 8, 10)

    PSP表格

    8ca384fa9b40ee6cf053638ba5812acd.png

    一、需求分析

    (1)能够自动生成简单运算的式子,可以定义其的数量和大小。

    (2)运算符要包括“+,-,×,÷”,其中还要支持括号和分数的计算。

    (3)程序要能够自己生成答案,并保存在文件夹中。

    (4)可以计算做对以及做错的题数和题号

    二、功能设计

    通过控制台生成四则运算,进行查重,将式子写入Exercise.txt中,

    计算每道题的结果写入Answer.txt

    在zuoda.txt中作答,通过比较,在Grade.txt中生成成绩

    三、设计实现

    65e9bb00203286cfc8895dcb4d75eea5.png

    四、关键代码

    //主页

    public classHomePage

    {public static void main(String[] args)throwsException

    {

    System.out.print("请输入生成的题目数量:");

    String input1=input();while (!isInt(input1)) {

    System.out.println("输入错误,请重新输入!");

    input1=input();

    }

    System.out.print("请输入题目的数值范围:");

    String input2=input();while (!isInt(input2)) {

    System.out.println("输入错误,请重新输入!");

    input2=input();

    }

    question ques= newquestion();

    ques.Exam(Integer.parseInt(input1), Integer.parseInt(input2));

    System.out.println("出题完毕,请到zuoda.txt作答!");

    System.out.println("如需批改请按‘1’,任意键退出");

    String input3=input();if (input3.equals("1")){

    CompareAnswer.compare();

    System.out.println("批改已完成,请到Grade.txt查看");

    }elseSystem.exit(0);

    }

    //生成式子

    public void Exam(int count,int range) throwsException

    {int re=0;

    String[] strr= new String[count+1];

    String[] strr2= new String[count+1];

    String[] repeat=new String[count+1];

    FileWriting.fileClear();

    String subject;for(int i=0;i

    {

    CreateFormula create=newCreateFormula();

    subject=create.Creating(range);//去掉多余括号

    subject=deleteKuoHao(subject);

    str=Check.chaChong(subject);

    strr[i]=str;

    strr2[i]=subject;int xy=1;for(int h=1;h

    {if(strr[h].equals(str))

    {

    xy=0;

    repeat[re]=h+","+strr2[h]+" Repeat "+i+","+subject;

    re++;break;

    }

    }if(xy==0)

    {

    i--;continue;

    }else{

    String result=Calculate.getResult(subject);

    FileWriting.writter((i+1)+":"+subject);

    FileWriting.writter1((i+1)+":"+result);

    FileWriting.writter2((i+1)+":");

    System.out.print("第"+(i+1)+"题,"+subject+"\n");

    }

    }

    //生成算式

    public class CreateFormula {

    private static char[] operate = { '+', '-', '*', '÷'};public String Creating(intrange){

    String subject= "";

    Random r= newRandom();int operator = r.nextInt(3)+1;//操作符个数

    int kuohao=0;boolean flag=true;for(int i=1;i<=operator;i++)

    {

    Random rand=newRandom();int temp=rand.nextInt(3)+1;if(temp==1)//决定是否加入左括号

    {

    subject+="(";

    kuohao++;

    subject+=this.getNum(range);

    subject+= this.getOperate();

    }else if (temp == 2 && flag) {//决定是否加入左括号

    flag=false;

    subject="("+subject;

    kuohao++;

    subject+=this.getNum(range);

    subject+= this.getOperate();

    }else if(temp==3&& kuohao!=0){//决定是否加入右括号

    subject+=this.getNum(range);

    subject+=")";

    kuohao--;

    subject+= this.getOperate();

    }else{

    subject+=this.getNum(range);

    subject+= this.getOperate();

    }

    }

    subject+=this.getNum(range);for(int i=kuohao;i>0;i--)

    {

    subject=subject+")";

    }returnsubject;

    }

    //计算

    public classCalculate {public staticString getResult(String s) {

    String result=Calculate.PRNCal(s);

    String[] ary= result.split("/");int a = Integer.parseInt(ary[0].trim());int b = Integer.parseInt(ary[1].trim());if (Math.abs(a)

    result= a + "/" +b;

    }else if (a ==b) {

    result= 1 + "";

    }else if (a == -b) {

    result= -1 + "";

    }else{intyu;intda;if (a == 0 || b == 0) {

    yu= 0;

    da= 0;

    }else{

    yu= a %b;

    da= a /b;

    }if (yu == 0)

    result= da + "";elseresult= da + "'" + Math.abs(yu) + "/" +Math.abs(b);

    }returnresult;

    }

    //对比答案

    public classCompareAnswer {private static String filePath2 = "answer.txt";private static String filePath3 = "zuoda.txt";public static void compare() throwsException {

    String right= "";

    String error= "";int correct=0;int wrong=0;

    InputStreamReader reader= new InputStreamReader(newFileInputStream(

    filePath2),"gbk");

    BufferedReader br= newBufferedReader(reader);

    String s= null;

    InputStreamReader reader1= new InputStreamReader(newFileInputStream(

    filePath3),"gbk");

    BufferedReader br1= newBufferedReader(reader1);

    String s1= null;int i = 0;

    right= "";

    error= "";while (((s = br.readLine()) != null) && (s1 = br1.readLine()) != null) {

    i++;if(s.trim().equals(s1.trim())) {

    correct++;

    right= right + i + ",";

    }else{

    wrong++;

    error= error + i + ",";

    }

    }

    String str1= "Correct:" +correct;if (right.length() <= 1)

    str1= str1 + "(" + ")";elsestr1= str1 + "(" + right.substring(0, right.length() - 1)+ ")";

    String str2= "Wrong:" +wrong;if (error.length() <= 1)

    str2= str2 + "(" + ")";elsestr2= str2 + "(" + error.substring(0, error.length() - 1)+ ")";

    FileWriting.fileClear();

    FileWriting.writter3(str1);

    FileWriting.writter3(str2);

    }

    }

    五、测试运行

    ae697916b0416829d6547c9a4707739a.png

    262f159da02977176c5309ef1fd7f04a.png

    e00093344445c60973f2035d9b445a73.png

    5afd272bae2dce910bfa10e443b041a6.png

    六、小结

    由于平时较少与人合作项目,此次与队友合作花费时间也较长,中间也遇到不少问题,不过遇到问题可以相互讨论,是一个人无法完成的。

    展开全文
  • Java实现) 整数区间

    千次阅读 2021-02-25 20:22:37
    一、题目描述给n个区间,形式为[a, b],a和b均为整数,且a <...= 10000)接下来n行,每行2个整数,表示区间的左右端点a, b(0 <=a < b <= 10000)输出第1行:1个整数,表示集合的元素的个...
  • 125. 验证回文串 难度简单398 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 **说明:**本题中,我们将空字符串定义为有效的回文串。 示例 1: ... //左右指针
  • 10万字208道Java经典面试题总结(附答案)

    万次阅读 多人点赞 2021-08-01 16:05:55
    JDK(Java Development Kit),Java开发工具包 JRE(Java Runtime Environment),Java运行环境 JDK中包含JRE,JDK中有一个名为jre的目录,里面包含两个文件夹bin和lib,bin就是JVM,lib就是JVM工作所需要的类库。...
  • // } // 必须是倒数第二步:判断小括号左右括弧是否等同,括弧位置是否合法,如果括弧全部合法,则去掉所有括弧 int num = 0; char[] expChars = expression.toCharArray(); for (int i = 0; i ; i++) { char temp =...
  • 入门算法 寻找峰值(java) 描述 山峰元素是指其值大于或等于左右相邻值的元素。给定一个输入数组nums,任意两个相邻元素值不相等,数组可能包含多个山峰。找到索引最大的那个山峰元素并返回其索引。 假设 nums[-1] ...
  • java详细学习路线及路线图

    万次阅读 多人点赞 2018-05-20 16:15:02
    java详细路线: 原文出自点击打开链接 本文将告诉你学习Java需要达到的30个目标,学习过程中可能遇到的问题,及学习路线。希望能够对你的学习有所帮助。对比一下自己,你已经掌握了这30条中的多少条了呢? ...
  • Java实现简易文本编辑器

    千次阅读 2020-02-17 18:26:30
    2)查找,替换(等长, 不等长),插入(插串,文本块的插入)、快移动(行块,列块移动),删除 3)可正确存盘、取盘 4)正确显示总行数 Q1:最初实现的界面如下图,“查看”是JMenu,将JMenu“缩放”添加到...
  • 一直持续FGC 5次左右,每次耗时1秒多不等。 FGC的原因实际上是内存不够用,但是运维反映堆内存是2G,从运维提供的参数看也是。 内存实际上一直只用到1G以内。 这时候可以自己写一段代码输出堆内存数据,这是最...
  • Java基础

    2020-12-24 18:25:15
    Java基础知识图解 Java基础概述 第一部分:编程语言核心结构 主要知识点:变量、基本语法、分支、循环、数组、… 第二部分:Java面向对象的核心逻辑 主要知识点:OOP、封装、继承、多态、接口、… 第三部分:开发...
  • java培训一般需要多少费用

    千次阅读 2021-03-22 15:24:57
    说到了Java的培训学习,应该很多人都想知道他的一个培训费用价格大概是在多少的范围之内,毕竟,Java培训现在是一个比较火爆的学习项目,许多人为了进入到Java行业,最终选择了Java培训这样的一条相比较快速的道路。...
  • Java语言中的常见错误

    2021-02-26 13:51:22
    Java语言中的常见错误导语:Java语言虽然功能强大,使用方便、灵活,但是要学好、用好Java语言并不容易。下面就由小编为大家介绍一下Java语言中的常见错误,欢迎大家阅读!1编译错误它是指在编写程序时,输入错误的...
  • 其实写Java的人貌似和CPU没啥关系,最多最多和我们在前面提及到的如何将CPU跑满、如何设置线程数有点关系,但是那个算法只是一个参考,很多场景不同需要采取实际的手段来解决才可以;而且将CPU跑满后我们还会考虑...
  • 聊聊Java和CPU的关系

    2021-02-12 09:01:35
    其实写Java的人貌似和CPU没啥关系,最多最多和我们在前面提及到的如何将CPU跑满、如何设置线程数有点关系,但是那个算法只是一个参考,很多场景不同需要采取实际的手段来解决才可以;而且将CPU跑满后我们还会考虑...
  • java四则运算

    2021-02-26 13:16:18
    5、比较Answer中填入的答案和calculate方法计算的答案 calculate方法产生的答案用double类型的数组results存起来,和数组ans比较,相等的话indexC(正确数目的计数器)+1,不等indexW(错误数目的计数器)+1。...
  • 介绍Oracle 在2017年3月左右发布Java新版本:Java SE9。陆续我会发表一系列有关Java SE 9新功能的文章。这是本系列的第三篇。我已经发表了几篇有关Java SE 9新特性的文章。在阅读这篇文章之前,请先阅读以下文章:在...
  • 解决垃圾收集(GC)暂停的问题 在垃圾收集过程中,整个应用程序可能会冻结几毫秒到几秒不等(延迟随着代码复杂度和堆大小而增加),更糟糕的是,你无法控制这种情况何时发生。虽然暂停一个应用程序几毫秒甚至几秒钟...
  • Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始写的新系列。 这些文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
  • Java基础知识总结

    2020-12-01 10:45:04
    Java基础 Final关键字: final可以用来修饰类、变量(包括成员变量和局部变量)和方法 修饰类 final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final...
  • 使用Java实现哈夫曼编码(Huffman Coding)

    千次阅读 多人点赞 2020-04-20 23:36:16
    (假设有n个权值) 以权值作为根节点构建n棵二叉树,组成森林 在森林中选出2棵根节点最小的树进行合并,作为一棵新树的左右子树,且新树的根节点为其左右子树根节点之和 从森林中删除刚才选取的2棵树,并将新树加入...
  • Java 语言中常用的运算符可分为如下几种:算术运算符赋值运算符比较运算符逻辑运算符条件运算符位运算符首发地址:JAVA位运算等运算符总结 )如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以加入...
  • 本文将告诉你学习Java的一些步骤,学习过程中可能遇到的问题,及学习路线。希望能够对你的学习有所帮助。 文末给大家准备了惊喜,希望大家都能够坚持看完哦~ 一、Java基础 二、Java学习七大阶段 [阶段1、...
  • Java中级开发面试题

    2020-05-19 17:28:02
    (一般面试官开始问你会从java基础问起,一问大多数会问到集合这一块,而集合问的较多的是HashMap,这个时候你就可以往这些方向带着面试官问你,而且扩展的深度也够,所以上面的干货够你说个十来分钟吧,第一个问题...
  • java里的Object

    万次阅读 2018-01-14 13:26:07
    这种方法的特点是:冲突发生时,在表的左右进行跳跃式探测,比较灵活。 ③ 伪随机探测 di=伪随机数序列;具体实现时,应建立一个伪随机数发生器,(如i=(i+p) % m),生成一个位随机序列,并给定一个随机数做起点,...
  • Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始写的新系列。 这些文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
  • Java到底要不要上培训班?

    千次阅读 2020-10-30 10:50:36
    请先分析一下自己,当前IT从业人员的平均工资水平确实远超于其他行业,但是你想过没有,越是很火的职业就越有人争先恐后的去,曾经有个玩笑,大街上随便拉个人都会Java,而且都是本科学历以上的,试问你能有什么竞争...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,535
精华内容 3,014
关键字:

java左右不等

java 订阅