그 외 공부
[객체기반SW설계] #TEST, JAVA TextAnalyzer
ssangeun
2015. 8. 6. 14:56
문제, 텍스트 파일을 읽어와서 파일에 있는 단어들의 정보를 분석하는 자바프로그램을 작성하시오.(제한시간 120분)
-code & 설명
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | package univ.inu.embedded; import java.util.*; public class TextAnalyzer { Hashtable<String,Integer> h=new Hashtable<String,Integer>(); //<단어 , 빈도수>의 정보를 가지고 있는 hashtable String totalS=null; //주변단어를 알기위한 전체 문자열 TextAnalyzer(){ } //생성자 //이름과 학번 출력 메소드 public String getName(){ return "이상은 201301674"; } //단어 추가 메소드 public void addWord(String _str){ String str=_str.trim(); str=str.toLowerCase(); //모든 단어를 대소문자 구분없이 비교하기 위새 소문자로 변환 //이 단계없이 단어들를 대소문자 구분없이 비교하기 위해서는 equalsIgnoreCase()메소드로 대체 가능 //1단계, 입력된 단어들을 이어서 전체 문자열 형성 if(totalS==null) { totalS=str; //처음으로 입력된 단어일 경우 } else { StringBuffer b=new StringBuffer(totalS); //단어들을 이어주기 위한 append메소드를 사용하기 위해서 String 변수를 StringBuffer로 변환 b.append(" "+str); //append를 사용해서 띄서쓰기 ' '와 단어를 함께 전체 문자열에 추가해준다. totalS=b.toString(); //StringBuffer로 변환된 String 변수를 다시 String으로 변환 } //2단계, 단어와 해당단어의 빈도수의 정보를 가지고 있는 h update if(h.containsKey(str)) //입력된 단어가 이미 있는 경우 { int cnt=(int)h.get(str); //중복된 단어가 현재 가지고 있는 빈도수를 get으로 가져온다. int ncnt=cnt+1; //단어가 또 입력되었으니 빈도수 증가 h.replace(str,cnt,ncnt); //h update } else //새로운 단어가 입력된 경우 { h.put(str, 1); //put 메소드를 사용하여 h에 단어 추가 } } //단어를 검색하면 hashtable의 정보를 이용하여 해당단어의 빈도수를 반환하는 메소드 public int getWordFrequency(String _str){ String str=_str.trim(); //단어의 불필요한 빈칸을 없애는 메소드 trim str=str.toLowerCase(); //대소문자 구분없이 비교하기위해 이미 정한 소문자의 설정대로 입력된 단어도 동등하게 소문자로 변환 if(h.containsKey(str)==false) //입력된 단어를 찾지 못한다면 { System.out.println("is not exist"); return -999; } else //입력된 단어를 찾았다면 해당단어의 빈도수 반환 { return (int)h.get(str); } } //단어의 길이를 검색하면 hashtable의 정보를 이용하여 해당단어의 길이를 가진 단어의 갯수를 계산하여 반환하는 메소드 public int getFrequencyByLength(int _len){ int temp=0; String cur; Set s=h.entrySet(); //hashtable의 전체 목록을 Set 타입의 s에 저장 Object[] t=s.toArray(); //s를 다루기 쉽게 배열로 변환 //단어와 빈도수의 정보를 배열로 변환결과 현재 배열에는 {'word1'='빈도수', 'word2'='빈도수', 'word3'='빈도수' ...}의 형태로 저장되어 있다. for(int i=0;i<t.length;i++) { String word=t[i].toString(); String[] r=word.split("="); //'='을 기준으로 문자열을 잘라서 새로운 배열에 넣는다. {'word1','빈도수'}의 형태로 저장되어있다. if(r[0].length()==_len) //배열의 0 인덱스에는 단어가 위치, 단어의 길이가 입력된 수와 같을 때 { String te=r[1]; //배열의 1 인덱스에는 해당단어의 빈도수가 위치 int numInt = Integer.parseInt(te); //string형태로 저장되어 있는 빈도수를 int형태로 변환 temp=temp+numInt; //단어 갯수 추가 } } return temp; //총 계산된 단어의 갯수를 반환 } //단어를 검색하면 전체 문자열을 이용하여 해당단어의 주변에 가장 많이 존재하는 단어를 반환하는 메소드 public String getMostNearbyWord(String _str){ String str=_str.trim(); str=str.toLowerCase(); Hashtable<String,Integer> a=new Hashtable<String,Integer>(); // < 단어 , 빈도수 > 주변에 어떤 단어가 가장 많이 존재하는지 판단하기 위해서 주변단어들과 해당단어들의 빈도수의 정보를 가지고 있는 hashtable String prev=null; //앞에 위치한 단어 String next=null; //뒤에 위치한 단어 String [] arr=totalS.split(" "); //전체 문자열을 ' '을 기준으로 잘라서 배열에 하나씩 저장 String [] array=new String[arr.length]; //빈칸이 중복되어 있을 경우 오로지 텍스트만 추출하는데 어려움이 있기 때문에 다시 ' '을 기준으로 잘라서 새로운 배열에 저장 for(int j=0;j<arr.length;j++) { String tem=arr[j]; array[j]=tem.trim(); } //단어들이 순서대로 저장되어잇는 배열을 이용하여 입력된 단어의 위치를 알아내고, 그 위치의 앞과 뒤에 있는 단어를 알아내는 과정 for(int i=0;i<array.length;i++) { if(array[i].equals(str)) //입력된 단어의 위치를 찾은 경우 { if(i==0) //단어의 위치가 배열의 가장 처음 위치라면 앞의 단어가 존재하지 않음 { next=array[i+1]; //뒤의 단어를 저장 (뒤의 단어 => 주변 단어 목록에 추가되어야 하는 대상) if(a.containsKey(next)) //주변단어가 이미 목록에 있다면 빈도수만 증가 { int cnt=a.get(next); int ncnt=cnt+1; a.replace(next,cnt,ncnt); } else //주변단어가 새로운 단어일 경우 put메소드를 사용하여 hashtable에 단어 추가 { a.put(next, 1); } } else if(i==array.length-1) //단어의 위치가 배열의 가장 마지막 위치라면 뒤의 단어가 존재하지 않음 { prev=array[i-1]; //앞의 단어를 저장 (앞의 단어 => 주변 단어 목록에 추가되어야 하는 대상) if(a.containsKey(prev)) //주변단어가 이미 목록에 있다면 빈도수만 증가 { int cnt=a.get(prev); int ncnt=cnt+1; a.replace(prev,cnt,ncnt); } else //주변단어가 새로운 단어일 경우 put메소드를 사용하여 hashtable에 단어 추가 { a.put(prev, 1); } } else //단어의 위치가 배열의 중간위치라면 앞과 뒤의 단어 모두 존재 { prev=array[i-1]; //앞의 단어를 저장 (앞의 단어 => 주변 단어 목록에 추가되어야 하는 대상) next=array[i+1]; //뒤의 단어를 저장 (뒤의 단어 => 주변 단어 목록에 추가되어야 하는 대상) if(a.containsKey(next)) //주변단어가 이미 목록에 있다면 빈도수만 증가 { int cnt=a.get(next); int ncnt=cnt+1; a.replace(next,cnt,ncnt); } else //주변단어가 새로운 단어일 경우 put메소드를 사용하여 hashtable에 단어 추가 { a.put(next, 1); } if(a.containsKey(prev)) //주변단어가 이미 목록에 있다면 빈도수만 증가 { int cnt=a.get(prev); int ncnt=cnt+1; a.replace(prev,cnt,ncnt); } else //주변단어가 새로운 단어일 경우 put메소드를 사용하여 hashtable에 단어 추가 { a.put(prev, 1); } } } } int more=0; Iterator it=a.values().iterator(); //가장 빈도수가 놓은 주변 단어를 검색하기 위해 hashtable에 있는 value들의 iterator메소드 사용 //모든 value들을 검색하여 가장 큰 수를 검색 while(it.hasNext()) { int temp=(int) it.next(); if(more<temp) { more=temp; //기존에 알려진 최대 빈도수보다 더 클 경우 최대 빈도수 update } } // ** 현재 최대 빈도수를 알고있는 상태, 최대 빈도수를 가지고 있는 단어를 검색할 단계 Set sa=a.entrySet(); //hashtable의 전체 목록을 Set 타입의 sa에 저장 Object[] t=sa.toArray(); //s를 다루기 쉽게 배열로 변환 //단어와 빈도수의 정보를 배열로 변환결과 현재 배열에는 {'word1'='빈도수', 'word2'='빈도수', 'word3'='빈도수' ...}의 형태로 저장되어 있다. for(int i=0;i<t.length;i++) { String word=t[i].toString(); String[] r=word.split("="); //'='을 기준으로 문자열을 잘라서 새로운 배열에 넣는다. {'word1','빈도수'}의 형태로 저장되어있다. String te=r[1]; //배열의 1 인덱스에는 단어가 해당단어의 빈도수가 위치 int numInt = Integer.parseInt(te); //string형태로 저장되어 있는 빈도수를 int형태로 변환 if(more==numInt) { return r[0]; //최대 빈도수를 가진 단어를 반환 } } return null; //단어를 찾지 못했을 때는 null값 반환 } } | cs |
- test하기 위해 사용하는 main code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | package univ.inu.embedded; import java.awt.font.TextAttribute; import java.io.*; import java.util.*; import java.util.regex.Pattern; import univ.inu.embedded.*; public class test { public static void main(String[] args) { TextAnalyzer textAnalyzer = new TextAnalyzer(); Scanner s = null; try { s = new Scanner(new File("test1.txt")); s = s.useDelimiter(Pattern.compile("[ \t\n\f\r\",.()]")); while (s.hasNext()) { String str = s.next(); if (str.length() < 2) { continue; } System.out.println("["+str+"]"); textAnalyzer.addWord(str); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("--- program ended --- \n\n ------------ Test ------------------\n\n"); System.out.println("프로그램 채점: "+textAnalyzer.getName()); String testStr1 = "Alfred"; System.out.println("Frequency of "+testStr1+" should be 14, yours is "+textAnalyzer.getWordFrequency(testStr1)); System.out.println("Frequency of "+testStr1.length()+" should be 57, yours is "+textAnalyzer.getFrequencyByLength(testStr1.length())); System.out.println("Most NearBy Word of "+testStr1+" should be hello, yours is "+textAnalyzer.getMostNearbyWord(testStr1)); } } | cs |
-text file
-결과