收藏 分销(赏)

ITAT编程习题分析.doc

上传人:仙人****88 文档编号:8323556 上传时间:2025-02-09 格式:DOC 页数:51 大小:846KB 下载积分:10 金币
下载 相关 举报
ITAT编程习题分析.doc_第1页
第1页 / 共51页
ITAT编程习题分析.doc_第2页
第2页 / 共51页


点击查看更多>>
资源描述
习题分析 ITAT第二届: 1、 编写一个Java程序要求:开启一个文本文件,一次读取其内的一行文本。令每一行形成一个String,并将读出的String对象置于LinkedList中。请以相反次序印出LinkedList内的所有文本行。 问题分析:1、需要IO流BufferedReader和FileReader类,通过IO流访问文本文件的每一行。2、Java框架中的LinkedList对象存储每一行。知道文本文件读完。3、通过LinkedList类的listIterator(int size)来实现遍历,通过hasPrevious()和previous()来实现逆序输出。 2、 用LinkedList实现一个stack,实现其中的push(),top()和pop()方法;其中push()实现向栈中加入一个元素,top()实现得到栈的最顶元素,pop()实现删除最顶元素。 问题分析:Stack的特征是:先进后出;通过LinkedList类的addLast(obj)方法实现push()方法;通过getLast()方法实现top()方法,通过removeLast()实现pop()方法。 3、 为Thread撰写两个子类,其中一个的run()在启动后取得第二个Thread object reference,然后调用wait()。另一个子类的run()在过了数秒之后调用notifyAll(),唤醒第一个线程,使第一个线程可以印出消息。 问题分析:1、ThreadSon和ThreadMain类实现Thread类。2、通过启动ThreadMain类的线程来调用ThreadSon线性。3、在ThreadSon类中定义ThreadMain类的对象main,通过对main对象的控制(锁旗标)实现运行ThreadSon后在运行ThreadMain类。4、具体实现: public class MainThread extends Thread { public void run() { sonThread son=new sonThread(this); //定义子线程的对象 son.start(); //在主线程中调用子线程 System.out.println("主线程等待..."); synchronized(this) //如果获得子线程的锁旗标就等待 { wait(); System.out.println("主线程启动..."); sleep(3000); System.out.println("主线程休眠3秒后..."); } System.out.println("主线程结束!"); } public static void main(String[] args) { MainThread main=new MainThread(); main.start(); } } class sonThread extends Thread { MainThread main=null; //定义主线程的对象 public sonThread(MainThread mian) { this.main=mian; } public void run() { synchronized (this) //获得对象的锁旗标 { System.out.println("子线程启动..."); sleep(3000); System.out.println("子线程休眠3秒后..."); } System.out.println("子线程结束!"); synchronized (main) { main.notify(); } //唤醒主线程 } } 4、 用Linklist实现一个队列quene;实现put()方法向队列中加入一个元素,get()方法得到第一个元素,isEmpty()判断是否为空。 问题分析:Queue的特征:先进先出;put方法和get方法实现通过调用LinkedList类的addList()方法和getFirst()方法;isEmpty方法的实现调用LinkedList类的isEmpty方法。 5、 撰写一个 myString class,其中包含一个String对象,可于构造函数中通过引数来设定初值。加入toString()和concatenate()。后者会将String对象附加于你的内部字符串尾端。请为myString()实现clone()。撰写两个static函数,令它们都接收myString referencex引数并调用x.concatenate(“test”)。但第二个函数会先调用clone()。请测试这两个函数并展示其不同结果。 问题分析:通过两个方法是先concatenate()和clone();通过对两个的调用和clone()方法,就会输出不同的结果。在这个题中考察的是clone()方法;还要注意一个小知识点:String str=str .concat(“test”);String的concat方法将指定字符串连接到此字符串的结尾。但只能将链接后的值赋值给其他字符串对象,不能赋值给str,即使赋值,但str的内容不会发生变化。String str+=”test”; 表示字符串链接,链接后将最新的值赋值给str,因此str的值发生变化了。此题的两个方法的实现: public static void Method1(MyStringTest MyStr){ System.out.println(MyStr.concatenate("test")); } public static void Method2(MyStringTest MyStr){ MyStr.clone()).concatenate("test")); } ITAT第三届 1、 编写一个Java应用程序,计算并输出一维数组(9.8,12,45,67,23,1.98,2.55,45)中的最大值和最小值。 问题分析:方法很多。方法一:通过循环实现输出最大值和最小值。方法二:通过把这些数存放到TreeSet中,输出第一个和最后一个就可以得到最大值和最小值。方法三:就是调用Java集合框架中Collections的max和min方法实现。方法四:通过Aarays类的Sort方法进行排序,然后输出第一个和最后一个就可以实现。 2、 编写一个Java应用程序,该程序使用FileInputStream类,实现从磁盘读取本应用程序源代码文件,并将文件内容显示在屏幕上。 问题分析:通过IO流中的类来实现从文件中读出,在屏幕上现实,具体实现: FileInputStream fis=new FileInputStream(file); BufferedReader br=new BufferedReader(new InputStreamReader(fis)); 通过把FileInputStream封装成InputStreamRead类,然后在封装成BufferedReader类。通过BufferedReader类实现读的操作。 FileInputStream 从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。BufferedReader从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 3、 编写一个Java应用程序,利用RandomAccessFile类,把几个int型整数(1,2,3,4,5,6,7,8,9,10)写入到一个名字为tom.dat文件中,然后按相反顺序读出这些数据并显示在屏幕上。(注意,一个int型数据占4个字节) 问题分析:1、通过RandomAccessFile类的writeInt()和ReadInt()实现把int整数写入到文件中,和从文件中读出。2、通过length()或getFilePointer()和seek(long pos)实现逆序的输出。Seek方法可以设置输输出的顺序。具体代码如下: RandomAccessFile raf=new RandomAccessFile(file, "rw"); for (int i = 1; i <=10; i++) { raf.writeInt(i); } // long getFilePointer()返回此文件中的当前偏移量。 long s=raf.getFilePointer(); for (int i = 1; i <=10; i++) { raf.seek(s-i*4); System.out.print(raf.readInt()+" "); } 4、编写一个Java应用程序,实现如下功能:   1)判断两个字符串是否相同,s1=”you are a student”,s2=”how are you”;   2)判断字符串”22030219851022024”的前缀、后缀是否和某个字符串”220302”相同;   3)按字典顺序比较两个字符串”你”和”我”的大小关系;   4)将数字型字符串”100”和”123.678”转换为数字; 5)将字符串”FEDCBA”存放到数组中,调用for循环读出数组数据显示在屏幕上。 问题分析:通过调用String类的方法实现:依次用到的方法有:startsWith(str2),endsWith(str2)、compareTo(Str)、Integer.parseInt(str1)、charAt(i); 5、编写一个Java应用程序,对用户输入的任意一组字符如{1,3,4,7,2,1,1,5,2},输出其中出现次数最多且数值最大的字符,并显示其出现次数。 问题分析:通过TreeMap对象来实现,对于已经包含在对象中就让其value加1;输出alue相同并且key最大的即可。迭代输出输出次数最多,且最大的方法是:通过迭代比较器key值,如果key比已经存在的key值大,通过比较其实value值,如果value的值比已经存在的值大,就交换其key和value的值,否则啥也不做。其代码: Iterator itr = hmap.keySet().iterator(); //对key值进行迭代 String str = (String) itr.next(); //把第一个key 付给str int times = hmap.get(str); //把第一alue付给times while (itr.hasNext()) //迭代循环 { String temp = (String) itr.next(); // 如果temp>str if (pareTo(temp) < 0) //比较下一个的key和str的大小 { int n = hmap.get(temp); //得到此key的次数 { if (times <= n) // temp的次数大于或等于str的次数 { //交换 str = temp; times = n; } } } } 6、 编写一个Java应用程序,使用Java的输入输出流技术将Input.txt的内容逐行读出,每读出一行就顺序为其添加行号(从1开始,逐行递增)并写入到另一个文本文件Output.txt中。 问题分析:通过读出文本的每一行,然后在写进文本时,在前面加如“n+"、"+”即可实现,每一次循环,n++即可,用的的流是BufferedReader、BufferedWriter、FileReader、FileWriter这四个类。 7、 编写一个Java应用程序,使用RandomAccessFile流统计Hello.txt中的单词,要求如下:(1)计算全文中共出现了多少个单词(重复的单词只计算一次);(2)统计出有多少个单词只出现了一次;(3)统计并显示出每个单词出现的频率,并将这些单词按出现频率高低顺序显示在一个TextArea中。 问题分析:首先通过IO流中的类实现输出每一行,然后在通过StringTolennl类实现对字符串的分割,分成一个的单词。通过把每一个单词添加到TreeMap中,如果此单词已经在TreeMap中,就让其alue加1;依次循环,直到把所有的单词添加到TtreeMap中。通过输出TreeMap的个数实现统计一共有多少个单词。通过对TreeMap进行对Value进行迭代,当其值等于1就让其加1,就可以实现统计多少个单词只出现一次。通过TreeMap类的对象进行对alue进行迭代,输出让频率大小输出,但是TreeMap对value进行迭代时,是无须的,所有必须实现这样: //此类是按对象的值进行排序的 class VluesDown implements Comparator { public int compare(Object o1, Object o2) { Entry<String, Integer> obj1 = (Entry<String, Integer>) o1; Entry<String, Integer> obj2 = (Entry<String, Integer>) o2; return obj2.getValue() - obj1.getValue(); } } 迭代输出: List list = new LinkedList(tmap.entrySet()); //根据指定比较器产生的顺序对指定列表进行排序 Collections.sort(list, new VluesDown()); Iterator itr = list.iterator(); while (itr.hasNext()) { Entry<String, Integer> entry = (Entry<String, Integer>) itr.next(); bw.write(entry.getKey() + "\t\t"); bw.write(entry.getValue() + ""); bw.newLine(); } bw.close(); 8、 编写一个Java应用程序,当用户在输入对话框中输入两个日期后(日期格式为YYYYMMDD,如1999年1月12日应输入为19990112),程序将判断两个日期的先后顺序,以及两个日期之间的间隔天数(例如1999年1月1日和1999年1月2日之间的间隔是1天)。 问题分析:通过GregorianCalendar类的进行初始化日期,通过调用该类的父类 Calendar的方法得到该日期一共有多少天。其代码如下: GregorianCalendar date; GregorianCalendar date1=new GregorianCalendar(1988,01,02); GregorianCalendar date2=new GregorianCalendar(1989,01,02); //得到此日期的天数 int datetime1=(int) (date1.getTimeInMillis()/(1000*60*60*24)); //得到此日期的天数 int datetime2=(int) (date2.getTimeInMillis()/(1000*60*60*24)); 通过比较datetime1和datetime2的差值,就可以实现此题的功能。 9、 编写一个Java应用程序,对于给定的一个字符串的集合,格式如: {aaa bbb ccc}, {bbb ddd},{eee fff},{ggg},{ddd hhh}要求将其中交集不为空的集合合并,要求合并完成后的集合之间无交集,例如上例 应输出:{aaa bbb ccc ddd hhh},{eee fff}, {ggg}  (1)分析问题,描述你解决这个问题的思路、处理流程,以及算法复杂度。(2)编程实现题目要求的集合合并。(3)描述可能的改进(改进的方向如效果,算法复杂度,性能等等)。 问题分析:1、通过把上面六个的字符串集合添加到LinkedList类的对象中,先把第一个字符串集合分割后都添加到TreeMap对象tmap中,然后对LinkedList迭代,迭代从第二个位置开始,对于每次循环,把得到的字符串进行分割,对于此循环,设置一个标识符,只要对于此次分割的单词在list1中出现,就把此分割的所有单词添加到tmap中。这样就可以实现两个集合的合并。对于所有分割后的单词都没有在tamp中出现,就把此字符串集合添加到list2中。当一轮循环后,需要判断list2中的集合是否有交集。如果有的话再次进行上面的循环。2、对于上面分割字符判断是否有交集,可以形成一个方法,类型为boolean,如果两个此集合和tmap有交集,就返回true,否则就返回false,通过在上个方法中调用此方法就可以判断。3、也可以把此字符串和tmap的字符串进行拆分在添加到tmap中。4、对于list2集合的判断,也可以写个方法,对于此list2的判断,返回值是boolean,同样在上个主方法中进行判断。具体实现代码如下: public class CollectionJava { LinkedList st; // 存储没有交集的集合 LinkedList list; public void Fun(LinkedList llist) { TreeSet set; // 存储有交集的集合 set = new TreeSet(); LinkedList te = new LinkedList(); Iterator litr = llist.iterator(); while (litr.hasNext()) { String str = (String) litr.next(); StringTokenizer token = new StringTokenizer(str); if (set.isEmpty()) // 开始为空时 { while (token.hasMoreTokens()) set.add(token.nextToken()); } else { if (Contin(set, str)) // set集合是包含str字符串某个元素 { while (token.hasMoreTokens()) set.add(token.nextToken()); } else te.add(str); // 通过set来屏蔽相同的 } } list.add(set); // 最后把set对象添加到list对象中 if (Contin2(te)) // 如果st对象的交集不为空,继续调用Fun()函数 { st.clear(); // 在移除te Fun(te); } else st = te; } // set对象是否含有str字符串的某个元素 public boolean Contin(TreeSet set, String str) { boolean flag = false; StringTokenizer token = new StringTokenizer(str, " "); while (token.hasMoreTokens()) { if (set.contains(token.nextToken())) flag = true; } return flag; } // 判断list对象的交集是否为空 public boolean Contin2(LinkedList list) { TreeSet et = new TreeSet(); int n = 0; boolean flag = false; Iterator lit = list.iterator(); while (lit.hasNext()) { String str = (String) lit.next(); StringTokenizer token = new StringTokenizer(str, "[ ]"); while (token.hasMoreTokens()) { n++; et.add(token.nextToken() + ""); } } if (et.size() == n) flag = false; else flag = true; return flag; } 10、在下图中的九个点上,空出中间的点,其余的点上任意填入数字1至8;1的位置保持·不动,然后移动其余的数字,使1到8顺时针从小到大排列。移动的规则是:只能将数字沿线移向空白的点。请将制作好的源文件保存为“t2.java”。(本题共60分,要求1占20分,要求2占40分) 要求: (1)分析问题,并描述你的算法设计思想。 (2)编程显示数字移动过程。 问题分析:1、通过ArrayList类的对象可以实现, 通过把1~8的数字添加到ArrayList类的对象中alist中, 然后在把他们对顺序打乱,通过Collections的 Shuffle(alist)的静态方法。并且索引为0的位置保存着0,通过第一位实现图中的中间位置。2、通过查找1的位置,找到之后,通过调整,把1放在索引为1的位置,1后的数字依次放在索引为1的后面,对于1前面的数依次放在最后元素的后面,类似与一个循环队列。3、开始进行移动,通过查找n(2~8),判断n是否在n-1的位置,如果不在,需要进行移动,移动的规则如下:先把n移近索引为0的位置,然后把n-1的索引位置x到n的索引位置y进行移动,把从索引为x的位置上元素移动到索引为y的位置上,依次类推,知道移动到n-1位置,然后把索引为0的位置元素移动到索引为n-1的位置,然后把索引为0的位置重新置为0 。具体代码如下: public class T2{ LinkedList<Integer> alist; // 初始化实现把1——8随即的放入图中那个,中间的位置相当于数组的索引0 public T2() { for (int i = 1; i < 9; i++) { alist.add(i); // 把i~8添加到alist中 } Collections.shuffle(alist); // 打乱alist对象的顺序 alist.add(0, 0); // 第0个位置相当与中的位置。用0代表是空的 } // alist对象中的第一个位置是1 public void SetFirst(){ int first = alist.indexOf(1); // 锁定1的位置 LinkedList<Integer> tem = new LinkedList<Integer>(); ListIterator listitr = alist.listIterator(first); while (listitr.hasNext()) tem.add((Integer) listitr.next()); // 把1后的元素添加的tem中 for (int i = 1; i < first; i++) tem.add(alist.get(i)); // 把1之前的元素添加到tem中 tem.add(0, 0); // 第一个位置相当与中的位置。用0代表是空的 alist = tem; // 赋给alist } public void Sort(){ this.SetFirst(); int flag = alist.indexOf(1); for (int n = 2; n < 9; n++){ // 此循环是实现调整2~9的位置 flag++; int tem = alist.indexOf(n); if (flag != tem) // flag后面的位置不是tem位置的元素 { // 把alist.get(tem)先放在索引为0的位置 alist.set(0, alist.get(tem)); for (int i = tem; i >= flag; i--){ // 把i-1的元素放到i位置上 alist.set(i, alist.get(i - 1)); } alist.set(flag, alist.get(0)); alist.set(0, 0); } } } 第四届ITAT 1、 编写一个Java应用程序,在其中编写一个类,该类封装了一元二次方程共有的属性和功能,即该类有刻画方程系数的3个成员变量以及计算实根的方法。并给出计算实根的过程。 问题分析:1、通过构造函数初始化一元二次方程的三个系数。2、通过一个参数判断方法有没有实根,类型是boolean的.3、计算方程的根,分三种情况:1)两个根相等,2)两个不相等实根,3)没有实根。4)还需要对一元二次方法的二次项的系数进行是否为0进行判断。 2、 编写一个Java应用程序,开启一个文本文件(以本程序源文件为例读取),一次读取其内的一行文本,令每行形成一个String,并将读出的String对象置于LinkedList中,以相反次序显示出LinkedList内的所有内容。 问题分析:见第二届 3、 Windows操作系统自带的计算器是个很方便的小工具,利用Java的GUI编程,实现一个Java GUI计算器应用程序界面,窗口标题为“计算器”,窗口布局如下图所示,在此计算器应用程序中实现“+、-、*、/”运算操作。 问题分析:通过switch进行+、-、*、/,通过对4求模,等于0进行+;等于1进行+;等于2进行*;等于3进行/;代码如下: switch (op1) { case 0: n1 = a + b; x = "+"; break; case 1: n1 = a - b; x = "-"; break; case 2: n1 = a * b; x = "*"; break; case 3: n1 = a / b; x = "/"; break; 4、 有500个小朋友拉成一个圆圈,从其中一个小朋友开始依次编号1-500,从1号小朋友开始循环1-3报数,数到3的小朋友就退出。编写一个Java应用程序,计算出最后一个小朋友的号码是多少 ? 问题分析:通过TreeSet的一个对象实现。首先把1—500的整数添加到对象tset中,然后对其进行循环变量,每当输出三次是,就取出这个数,把这个付给tem,循环结束,tem就是所求的结果。上面实现的是1就是第一个小朋友。同样也可以产生一个随机数,把他当作第一小朋友,进来就对他们进行重新排序,实现算法类似于第三届ITAT中的第十个题,实现重新排序后,就可以进行上述的遍历循环。 5、 水仙花数是指其个位、十位、百位三个数的立方和等于这个数本身。编写一个Java应用程序,求出所有水仙花数。 问题分析:首先求出三位数的个位、十位、百位;然后进行判断即可。代码如下: c=num%10;//个位 b=(num/10)%10;//十位 a=num/100; //百位 6、 编写一个Java应用程序,利用RandomAccessFile类往某个文本文件中写入20个整数(0~19),然后从该文件的第12个字节开始,将后面所有的数据(对应写入的整数)读出。 问题分析:此题的分析类似于第三届的第三题。具体实现如下: //写入流 RandomAccessFile raf=new RandomAccessFile("D://raf.java", "rw"); for(int i=0;i<20;i++) raf.writeInt(i); //输出流 long len=raf.length(); System.out.println(len); for(int i=12;i<len/4;i++) raf.seek(i*4); int x=raf.readInt(); System.out.println(x); 7、 采用Java 多线程技术,设计实现一个符合生产者和消费者问题的程序。对一个对象(枪膛)进行操作,其最大容量是12颗子弹。生产者线程是一个压入线程,它不断向枪膛中压入子弹;消费者线程是一个射出线程,它不断从枪膛中射出子弹。 要求:   (1)给出分析过程说明。   (2)程序输出,要模拟体现对枪膛的压入和射出操作;   (3)设计程序时应考虑到两个线程的同步问题。 问题分析:1、四个类:子弹类,生成者类、消费者类、主类;2、子弹类:对一些参数的初始化。方法有生成和消费的方法,两个方法主要共享子弹生成的数目。3:生成类:实现对生成方法的调用。4:实现对消费的方法调用。5:生成类和消费类都有一个子弹的对象。对于子弹类的两个主要的方法都用Synchronize休息。具体代码实现如下: // 对一个对象(枪膛)进行操作,其最大容量是12颗子弹。 class ZiDan { int size = 0; // 子弹总量 int number = 0; // 可以子弹 boolean avaiable; // 控制字段压入和射出操作 public ZiDan(int size) // 带参数的构造函数 { this.size = size; avaiable = false; } // 压入子弹 public synchronized void Push() { if (avaiable) // 如果有子弹,等待 wait(); System.out.println("向枪膛中压入子弹 " + (++number)); avaiable = true; notify(); // 释放对象锁旗标 } //从枪膛中射出子弹 public synchronized void Pop() { if (!avaiable) // 如果没有子弹,等待 { wait(); } System.out.println("从枪膛中射出子弹 " + number); avaiable = false; notify(); if(number==size) number++; } } // 生产者线程是一个压入线程,它不断向枪膛中压入子弹; class Producer extends Thread { // 字段 ZiDan zd; // 构造函数 public Producer(ZiDan zd) { this.zd = zd; } public void run() { while (zd.number < zd.size) // 当子弹的数量小于子弹的总量 zd.Push(); System.out.println("子弹压入结束!"); } } // 消费者线程是一个射出线程,它不断从枪膛中射出子弹。 class Consumer extends Thread { // 字段 ZiDan zd; int i = 0; // 构造函数 public Consumer(ZiDan zd) { this.zd = zd; i = 0; } public void run() { while (zd.number <= zd.size) // 循环条件:子弹的数量小于总量 zd.Pop(); System.out.println("射出子弹结束!"); } } 8、某企业为了促销,搞抽奖宣传活动,奖品为新款手机一部,抽奖规则如下: (1)有n个盒子摆成一圈,盒子按顺时针方向依次编号为0,1,2,……,n-1。手机随 机放在其中一个盒子中。(n为自然数) (2)从0号盒子开始摸奖,顺时针方向计数,每遇到第m个盒子就摸奖一次。(m为自然数,m<n)   (3)直到重新摸到0号盒子为止。   例如n=5,m=3,那么摸奖经过的盒子编号依次为0,3,1,4,2,0。 请编写一个完整的程序,随机输入n,m(m<n),程序分析手机有没有不被抽中的机会?如果有,概率是多少? (概率=不被抽中的可能数/n)。 问题分析:1、通过产生三个随机数,第一随机数表示盒子的个数,第二随机数表示每次隔几个盒子摸奖,第三个随机数表示奖品放在这个标号的盒子中。2、把n个盒子的序号当作TtreeMap当作key,把从去有奖品的盒子外,所有的盒子的alue都初始化null;有手机的初始化“Mobile”;3、实现对对n个盒子的循环,对此间隔m个盒子,当此键的值等于“Mobile”时,中间,如何循环到n=0时,就结束,没有中奖。具体实现如下: public class MobileTest { int n,m,x; ArrayList alist; public MobileTest() { alist=new ArrayList(); int tem1,tem2; tem1=(int)(Math.rando
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 教育专区 > 小学其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服