号外:之前的几篇编码博客,总觉得哪里有问题。而且每次都在java的输入面前折腾一会儿。今天看了室友的代码终于知道问题在哪里了。他的博客传送门ROPEAL。
正所谓操千曲而后晓声,观千剑而后识器。看别人代码而知自己代码之不足…..行行行,不bb了行不。好了上题目,操代码。
题目:开发一个简单错误记录功能小模块,能够记录出错的代码坐在的文件名称和行号。
处理:
1.记录最多8条错误记录,对相同的错误记录(即文件名称和行号完全匹配)只记录 一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并)
2.超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并)
3.输入的文件可能带路径,记录文件名称不能带路径
思路
正所谓:兵马未动粮草先行。思想要先行。
这里有几个代码块,输入、字符串处理(空格分开)、容器排序。这里可以使用一个线性表,每一次存入下一个数据之前要对之前的数据进行比较(代码xx行),相同的则要增加数目(代码xx行)。然后容器排序,最后是后期处理,把多余8行的干掉。
代码奉上
/**
* @author ziling
*
2015年9月2日
*/
public class FileErrorCount2016 {
public static void main(String[] args) {
Scanner sca = new Scanner(System.in);
List<fileCounts> l = new ArrayList<fileCounts>();
String input =sca.nextLine();
do{
fileCounts fc = tmp(input);
int nums = l.size();
if(nums == 0){
l.add(fc);
nums = l.size();
}else{
boolean b = false;
//逐个进行比较,看看是否有重复的类。
for(int i = 0; i<nums; i++){
b = fc.equals(l.get(i));
}
if(b == false){
l.add(fc);
}
}
input = sca.nextLine();
}while(!(input.equals("") || input==null));
//对于线性表进行排序
l.sort(new Comparator<fileCounts>() {
@Override
public int compare(fileCounts o1, fileCounts o2) {
if(o1.getCount() > o2.getCount())return 1;
return 0;
}
});
//最后,后期处理。保留前边八个数据。更新文件的名称。把后面的remove掉。
for(int i = 0; i < l.size(); i++){
if(i<8){
fileCounts fc1 = l.get(i);
String s = fc1.getFileName();
if(s.length() > 16){
fc1.setFileName(s.substring(s.length()-16, s.length()));//获取后面16个字符作为文件的名称。
}
System.out.println(fc1.getFileName()+" "+fc1.getLines()+" "+fc1.getCount());
}else {
l.remove(i);
}
}
sca.close();
}
//对于输入的字符串进行处理,得到封装的fileCounts类。
public static fileCounts tmp (String s){
String s1[] = s.split(" ");//已空格为分割符号得到字符数组,这里就两个。一个是文件名,一个是行号
String s2 = s1[0];
String fileName="";
for(int i = s2.length()-1; i >=0; i--){
if(s2.charAt(i) == '\\'){
fileName = s2.substring(i+1, s2.length());//字符串的剪切
break;
}
}
if(fileName =="")fileName = s1[0];//考虑这样的输入 d.txt 123。此时并没有带盘符。
fileCounts fc = new fileCounts();
fc.setCount(1);
fc.setFileName(fileName);
fc.setLines(Integer.valueOf(s1[1]));
return fc;
}
static class fileCounts{
private String fileName;
private int lines;
private int count;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public int getLines() {
return lines;
}
public void setLines(int lines) {
this.lines = lines;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public boolean equals(fileCounts f2){
if(this.getFileName().equals(f2.getFileName()) && this.getLines() == f2.getLines()){
int tmp = f2.getCount();
f2.setCount(++tmp);
return true;
}else
return false;
}
}
}
好了,最后在想写两句,发现都已经写在代码里了。好吧,已经无力吐槽。
号外1:关于java输入模式,这里指的是在下一次不输入就算是输入结束了。
而在c++中。while()的判断可以不用false/true,可以用while(cin>>value),然后配合ctrl+z结束。java的while()必须要接受false/true
Scanner sca = new Scanner(System.in);
String input = sca.nextLine();
do{
//input处理,利用split进行字符串的分割,利用Integer包装类,进行字符串的转其他类型,如int等
String s1[] = input.split(" ");
input = sca.nextLine();//再次接入
}while(!(input.equals("") || input==null));
sca.close();
2015-09-21
号外2:在号外1中关于java的输入的说法是错误的
在程序中实现如下,在这样的程序中,依然可以用crl+z结束。
while(sca.hasNext()){
new Behappy().test();
String input = sca.nextLine();
//input处理,利用split进行字符串的分割,利用Integer包装类,进行字符串的转其他类型,如int等
String s1[] = input.split(" ");
for(int i = 0; i < s1.length; i++){
System.out.print(s1[i]+" ");
}
}
号外三:在程序中关于在ArrayList的数据删除的问题。这是一个陷进,需要特别注意。同样也困扰了我。以至于在机试的时候没有得到满分。如下代码分别采用了两种删除的方式,for语句,和迭代器
//1/删除制定元素,在删除元素之后,arrayList会进行移位的操作。也就是说,把空的部分重新填上
// for(int index = 0, len = l.size(); index < len; index ++){
// System.out.print(l.get(index)+ " ");
// if(l.get(index) == "x") {
// l.remove(index);
// --len;
// --index;
// }
//
// }
Iterator<String> i = l.iterator();
while(i.hasNext()){
String tmp = i.next();
if(tmp == "x") i.remove();
System.out.print(tmp+" ");
}