福大软工1816 · 第二次作业

github 地址:传不了,2kb/s 我传到明年好不好

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 10 12
· Estimate · 估计这个任务需要多少时间 10 12
Development 开发 135 196
· Analysis · 需求分析 (包括学习新技术) 15 28
· Design Spec · 生成设计文档 0 0
· Design Review · 设计复审 0 0
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 10 20
· Design · 具体设计 20 30
· Coding · 具体编码 60 80
· Code Review · 代码复审 10 8
· Test · 测试(自我测试,修改代码,提交修改) 20 30
Reporting 报告 3 3
· Test Repor · 测试报告 1 1
· Size Measurement · 计算工作量 1 1
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 1 1
|       | 	合计  |148 |211

  • 解题思路描述:

    • 一开始看到这个题目,我内心是拒绝的,我不能说用Visual Studio Community 2017就用Visual Studio Community 2017,因为我没有windows。那只能用java了,而我java更加不熟练,大部分语句都是三年前学的几乎已经忘光了。所以我只好先看看java怎么写 = = 碰巧电脑里面保存了很早之前编写过的java代码,于是直接就可以开始了。
    • 首先创建一个主程序类,用于io流的输入和输出。
    • 其次创建一个计算类,用于分析读入的文本。
    • 由于无视大小写字母,且输出为小写模式,因此应把读入的字符串全部转为小写方便操作。
    • 统计文件字符数,因为不需要统计汉字,于是遍历字符串,计算其Ascal码小于178的总数。
    • 统计单词总数,创建一个过程,遍历字符串。由于需要至少四个英文字母开头,计数开头英文字母数量,当开头字母数量为4以上,并且读到分隔符,单词数加加。
    • 有效行数,读入文件时一行一行读入,字符串为空的跳过即可。
    • 统计单词出现次数,运用哈希表存储,方便代码编写,最后对其排序输出。
  • 设计实现过程:

    • 代码设计为两个类,分别为 main 和 St。

    • main 类作为主程序使用。

      • 调用java.io库在main内实现对input.txt的读入,和result.txt的输出。
      • 把得到的字符串传递至St类进行分析。
      • 调用St类内的函数,得到分析完成的答案。
    • St 类用于分析得到的字符串。

      • 过程getS(String)用于从主程序得到目标字符串,将字符串英文字母转为小写,并调用分析过程St1(),St2()。
      • 过程St1() 用于计算字符串内字符数,仅计算ascal码小于178的字符,由getS(String)调用。
      • 过程St2()用于计算字符串内单词数量,并调用wordPush(String)过程,传递单词。
      • 过程wordPush(String) 把得到的单词压入哈希表,统计每个单词出现次数。
      • 函数outWordN() 把哈希表复制给List排序后,函数返回输出答案的字符串。
      • 函数outsl() 和 outws() 分别返回字符数和单词数 的输出答案。
  • 程序改进:

    • 写完就这样,我觉得挺好的,不用改

    • 「 VS 2017的性能分析工具 」是什么?

  • 代码说明:

    • I/O流输入输出。百度了一下,借用了别人的程序进行修改 https://www.cnblogs.com/pyj03/p/7699113.html

          St begin =new  St();    // 这里创建一个新 St()类!!!!
          try { // 防止文件建立或读取失败,用catch捕捉错误并打印,也可以throw  	  
              /* 读入TXT文件 */  
              String pathname = "./src/input.txt"; // 绝对路径或相对路径都可以,这里是绝对路径,写入文件时演示相对路径  
              File filename = new File(pathname); // 要读取以上路径的input。txt文件  
              InputStreamReader reader = new InputStreamReader(  
                      new FileInputStream(filename)); // 建立一个输入流对象reader  
              br = new BufferedReader(reader);
              String line = "";  
              for (line=br.readLine();line!=null; line=br.readLine()){
              	 begin.getS(line);    //把输入流得到的字符串传给St类
              	 if (line.length()>0) ko++;    // 不记录空行
              }
              /* 写入Txt文件 */  
              File writename = new File("./src/result.txt"); // 相对路径,如果没有则要建立一个新的output。txt文件  
              writename.createNewFile(); // 创建新文件  
              BufferedWriter out = new BufferedWriter(new FileWriter(writename));  
              out.write(begin.outsl()+"\r\n");    //输出字符数
              out.write(begin.outws()+"\r\n");    //输出单词数
              out.write("lines: "+String.valueOf(ko)+"\r\n");    //输出行数
              out.write(begin.outWordN());    //输出排序后的单词
              out.flush(); // 把缓存区内容压入文件  
              out.close(); // 最后记得关闭文件  
      
          } catch (Exception e) {  
              e.printStackTrace();  
          }  
      

    }
    ```

    • St1(),统计字符数,由于ascal码大多数在178以内,而汉字通常很大,所以只统计178以内数量

          	public void st1(){
      for(int i=0;i<s.length();i++){
      	char ch = s.charAt(i);
      	int j=(int)ch;
      	if (j<178) sl++;
      	}
      

    }
    ```

    • St2(),统计单词数,函数syadann(int)返回boolean,判断是否为分隔符,函数eigo(int)返回boolean,判断是否为英文字母。

          	public void st2(){
      int k=0;                //单词前英文字母数量
      boolean ikeru=true;    //字符是否暂时只出现英文字母
      String th="";        // th 用于记录这个单词
      for(int i=0;i<s.length();i++){
      	char ch = s.charAt(i);
      	int j=(int)ch;
      	if (!syadann(j)){    th=th+ch;    } // 不是分隔符便记录
      	if (ikeru && eigo(j)){ 
      		k++;    // 出现的英文字母加 1
      	}else if (ikeru && !eigo(j)) ikeru=false;  //单词间出现了非英文字母字符
      	if (syadann(j) || i==s.length()-1) {
      		if (k>=4) {                //此单词开头出现了大于4个的英文字母,符合单词构成
      			ws++;
      			wordPush(th);    //把单词放入wordPush()过程内
      		}
      		ikeru=true;
      		k=0;
      		th="";
      	}
      }	
      

    }
    ```

    • wordPush(String) ,把从St2()过程得到的符合单词规则的单词,压入哈希表,已存在 则记录个数加1

          	private void wordPush(String sk) {
      if(wordSet.contains(sk))
      {
      	Integer number=hashMap.get(sk);
      	number++;
      	hashMap.put(sk, number);
      }
      else 
      {
      	hashMap.put(sk, 1);
      }
      

    }
    ```

    • 函数outWordN() 返回答案字符串。通过查询得知Collections.sort排序只能用于list,所以创建两个List 来存放哈希表的内容。由于快速排序有点不太记得,就暴力地排序了两遍,把已经按字典序排序的list里面按顺序,把前十个出现次数最多的数抽出来。

          	public String outWordN(){
      String kk="";
      List<String> list=new ArrayList<String>(wordSet);
      List<Integer> list2=new ArrayList<Integer>();
      Collections.sort(list);
      for(int i=0;i<list.size();i++) list2.add(hashMap.get(list.get(i)));	
      Collections.sort(list2);
      for (int j=1; j<=10; j++)
      	for (int i=0;i<list.size();i++){
      		if (hashMap.get(list.get(i))==list2.get(list2.size()-j)){
      			kk=kk+"<"+list.get(i)+">: "+hashMap.get(list.get(i))+"\r\n";
      			list.remove(i);
      			break;
      		}
      	}
      return kk;
      

    }
    ```

  • 样例

  • 源代码之main 类

import java.io.*;
public class main {
	private static int ko=0;
	private static BufferedReader br;
	
	public static void main(String[] args) {
		St begin =new  St();
		
		
		  try { // 防止文件建立或读取失败,用catch捕捉错误并打印,也可以throw  
			  
	            /* 读入TXT文件 */  
	            String pathname = "./src/input.txt"; // 绝对路径或相对路径都可以,这里是绝对路径,写入文件时演示相对路径  
	            File filename = new File(pathname); // 要读取以上路径的input。txt文件  
	            InputStreamReader reader = new InputStreamReader(  
	                    new FileInputStream(filename)); // 建立一个输入流对象reader  
	            br = new BufferedReader(reader);
	            String line = "";  
	            for (line=br.readLine();line!=null; line=br.readLine()){
	            	 begin.getS(line);
	            	 if (line.length()>0) ko++;
	            }
	  
	            /* 写入Txt文件 */  
	            File writename = new File("./src/result.txt"); // 相对路径,如果没有则要建立一个新的output。txt文件  
	            writename.createNewFile(); // 创建新文件  
	            BufferedWriter out = new BufferedWriter(new FileWriter(writename));  
	            out.write(begin.outsl()+"\r\n");
	            out.write(begin.outws()+"\r\n");
	            out.write("lines: "+String.valueOf(ko)+"\r\n");
	            out.write(begin.outWordN());
	            out.flush(); // 把缓存区内容压入文件  
	            out.close(); // 最后记得关闭文件  
	  
	        } catch (Exception e) {  
	            e.printStackTrace();  
	        }  
	}
}
  • 源代码之St类

import java.util.*;

public class St {
	private static String s;
	private static int sl=0;
	private static int ws=0;
	private HashMap<String, Integer > hashMap=new HashMap<String,Integer>();
	private Set<String> wordSet=hashMap.keySet();
	public String outsl(){	return 	"characters: "+String.valueOf(sl);	}
	public String outws(){	return "words: "+String.valueOf(ws);	}
	public String outWordN(){
		String kk="";
		List<String> list=new ArrayList<String>(wordSet);
		List<Integer> list2=new ArrayList<Integer>();
		Collections.sort(list);
		for(int i=0;i<list.size();i++) list2.add(hashMap.get(list.get(i)));	
		Collections.sort(list2);
		for (int j=1; j<=10; j++)
			for (int i=0;i<list.size();i++){
				if (hashMap.get(list.get(i))==list2.get(list2.size()-j)){
					kk=kk+"<"+list.get(i)+">: "+hashMap.get(list.get(i))+"\r\n";
					list.remove(i);
					break;
				}
			}
		return kk;
	}
	public boolean syadann(int c){
		if (c>=48 && c<=57) return false;
		if (c>=65 && c<=90) return false;
		if (c>=97 && c<=122) return false;
		return true;
	}
	public boolean eigo(int c){
		if (c>=65 && c<=90) return true;
		if (c>=97 && c<=122) return true;
		return false;
	}
	public void getS(String s){
		if (s!=null){
		    St.s=s.toLowerCase();
		    st1();
			st2();
		}
	}
	private void wordPush(String sk) {
		if(wordSet.contains(sk))
		{
			Integer number=hashMap.get(sk);
			number++;
			hashMap.put(sk, number);
		}
		else 
		{
			hashMap.put(sk, 1);
		}
	}
	public void st1(){
		for(int i=0;i<s.length();i++){
			char ch = s.charAt(i);
			int j=(int)ch;
			if (j<178) sl++;
			}
	}
	public void st2(){
		int k=0;
		boolean ikeru=true;
		String th="";
		for(int i=0;i<s.length();i++){
			char ch = s.charAt(i);
			int j=(int)ch;
			if (!syadann(j)){
				th=th+ch;
			}
			if (ikeru && eigo(j)){
				k++;
			}else if (ikeru && !eigo(j)) ikeru=false;
			if (syadann(j) || i==s.length()-1) {
				if (k>=4) {
					ws++;
					wordPush(th);
				}
				ikeru=true;
				k=0;
				th="";
			}
		}	
	}
}


posted on 2018-09-12 20:51  YooRarely  阅读(217)  评论(0编辑  收藏  举报

导航