Thống kê ký tự trong file và vẽ biểu đồ
Viết chương trình cho phép đọc 1 file dạng text, hiển thị nội dung file đó và vẽ biểu đồ số lần ký tự từ A-> Z không phân biệt hoa thường xuất hiện.
Cửa sổ sau khi nhấn nút “Load File” như sau:
Sau khi nhấn nút “Character Statitics” ta có hình thống kê như sau
Đầu tiên ta viết module để thống kê. Java có tập các xử lý tập hợp rất hay, đặc biệt về set/map.
Ta xây dựng 1 map lấy các ký tự từ a đến z làm khóa, còn các giá trị tương ứng với khóa là 1 số nguyên để chỉ số lần xuất hiện. Map của ta sẽ có dạng: TreeMap<Character, Integer>
Ta duyệt qua từng ký tự trong file và ta xem nó có trong map chưa, nếu có thì ta cộng thêm 1 vào value. Như vậy ta sẽ thống kê được số lần xuất hiện của 1 ký tự trong file.
Code của file CharacterStatitics.java như sau:
package vovanhai.wordpress.com; import java.awt.Color; import java.io.FileInputStream; import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.TreeMap; import javax.swing.JDialog; public class CharacterStatitics { private String sourceFile; public CharacterStatitics(String sourceFile) { this.sourceFile = sourceFile; } /** * Đếm số lần ký tự từ A->Z xuất hiện trong file * @return */ public TreeMap<Character, Integer> CountCharacter() { TreeMap<Character, Integer> bag=new TreeMap<Character, Integer>(); for(int i='A';i<='Z';i++){ bag.put((char)i, 0); } try { Scanner sc=new Scanner(new FileInputStream(sourceFile)); String line=""; while(sc.hasNextLine()) { line=sc.nextLine(); line=line.toUpperCase(); for (int i = 0; i < line.length(); i++) { char c=line.charAt(i); Integer num=bag.get(c); if(num!=null){ num+=1; bag.put(c, num); } } } sc.close(); } catch (Exception e) { e.printStackTrace(); } return bag; } /** * Xây dựng biểu đồ * @return */ public JDialog GetStatitisChart(){ TreeMap<Character, Integer> bag=CountCharacter(); Set<Map.Entry<Character, Integer>>entries=bag.entrySet(); String []names=new String[26]; double[] values = new double[26]; int i=0; for(Map.Entry<Character, Integer>entry:entries){ names[i]=entry.getKey().toString(); values[i]=entry.getValue(); i++; } JDialog frm = new JDialog(); frm.setModal(true); frm.setTitle("https://vovanhai.wordpress.com - CharacterStatitics"); frm.setSize(400, 300); ChartPanel pane=new ChartPanel(values, names, "Biểu đồ thống kê ký tự trong file",Color.blue,Color.red); frm.getContentPane().add(pane); frm.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); return frm; } }
Code cho file ChartPanel.java như sau:
package vovanhai.wordpress.com; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import javax.swing.JPanel; public class ChartPanel extends JPanel { private double[] values; private String[] names; private String title; private Color chartColor; private Color boderColor; public ChartPanel(double[] v, String[] n, String t) { names = n; values = v; title = t; this.chartColor = Color.red; this.boderColor = Color.black; } public ChartPanel(double[] values, String[] names, String title, Color chartColor, Color boderColor) { this.values = values; this.names = names; this.title = title; this.chartColor = chartColor; this.boderColor = boderColor; } public void paintComponent(Graphics g) { super.paintComponent(g); if (values == null || values.length == 0) return; double minValue = 0; double maxValue = 0; for (int i = 0; i < values.length; i++) { if (minValue > values[i]) minValue = values[i]; if (maxValue < values[i]) maxValue = values[i]; } Dimension d = getSize(); int clientWidth = d.width; int clientHeight = d.height; int barWidth = clientWidth / values.length; Font titleFont = new Font("SansSerif", Font.BOLD, 20); FontMetrics titleFontMetrics = g.getFontMetrics(titleFont); Font labelFont = new Font("SansSerif", Font.PLAIN, 10); FontMetrics labelFontMetrics = g.getFontMetrics(labelFont); int titleWidth = titleFontMetrics.stringWidth(title); int y = titleFontMetrics.getAscent(); int x = (clientWidth - titleWidth) / 2; g.setFont(titleFont); g.drawString(title, x, y); int top = titleFontMetrics.getHeight(); int bottom = labelFontMetrics.getHeight(); if (maxValue == minValue) return; double scale = (clientHeight - top - bottom) / (maxValue - minValue); y = clientHeight - labelFontMetrics.getDescent(); g.setFont(labelFont); for (int i = 0; i < values.length; i++) { int valueX = i * barWidth + 1; int valueY = top; int height = (int) (values[i] * scale); if (values[i] >= 0) valueY += (int) ((maxValue - values[i]) * scale); else { valueY += (int) (maxValue * scale); height = -height; } g.setColor(chartColor); g.fillRect(valueX, valueY, barWidth - 2, height); g.setColor(boderColor); g.drawRect(valueX, valueY, barWidth - 2, height); int labelWidth = labelFontMetrics.stringWidth(names[i]); x = i * barWidth + (barWidth - labelWidth) / 2; g.drawString(names[i], x, y); g.drawString(((int)values[i])+"", x-2, valueY); } } }
code cho file Editor.java như sau:
package vovanhai.wordpress.com; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileInputStream; import java.util.Scanner; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.filechooser.FileFilter; public class Editor extends JFrame implements ActionListener{ private JTextArea taContent; private JButton btnStatitis; private JButton btnLoadFile; private String selFile=""; public Editor() { setTitle("https://vovanhai.wordpress.com"); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(500,500); add(new JScrollPane(taContent=new JTextArea(30,40))); JPanel p=new JPanel(); this.add(p,BorderLayout.SOUTH); p.add(btnLoadFile=new JButton("Load File")); p.add(btnStatitis=new JButton("CharacterStatitics")); btnStatitis.addActionListener(this); btnLoadFile.addActionListener(this); } @Override public void actionPerformed(ActionEvent e) { Object o=e.getSource(); if(o.equals(btnLoadFile)){ JFileChooser fc=new JFileChooser(); fc.setFileFilter(new FileFilter() { @Override public String getDescription() { return "Text file (*.txt)"; } @Override public boolean accept(File f) { return f.isDirectory()||f.getName().endsWith(".txt"); } }); if(fc.showDialog(null, "Chọn File")==JFileChooser.APPROVE_OPTION){ selFile=fc.getSelectedFile().getAbsolutePath(); try { taContent.setText(""); final Scanner sc=new Scanner(new FileInputStream(selFile),"UTF-8"); new Thread(new Runnable() { @Override public void run() { while(sc.hasNextLine()){ String line=sc.nextLine()+"\n"; taContent.append(line); } } }).start(); } catch (Exception e2) { e2.printStackTrace(); } } } else if(o.equals(btnStatitis)){ if(!selFile.trim().equals("")){ CharacterStatitics f=new CharacterStatitics(selFile); JDialog frm=f.GetStatitisChart(); frm.setVisible(true); } } } }
Code cho lớp Starting.java để chạy chương trình như sau
package vovanhai.wordpress.com; public class Starting { public static void main(String[] args) { new Editor().setVisible(true); } }
Cấu trúc tổ chức của các lớp như sau:
Chúc bạn thành công!
phanhongminh said
nhưng em strarting xong chay editor ma không chay ra gì hết thầy
Danh said
thầy ơi đoạn code này em không hiểu thầy giải thich dùm em được không thầy
for (int i = 0; i = 0)
valueY += (int) ((maxValue – values[i]) * scale);
else {
valueY += (int) (maxValue * scale);
height = -height;
}
g.setColor(chartColor);
g.fillRect(valueX, valueY, barWidth – 2, height);
g.setColor(boderColor);
g.drawRect(valueX, valueY, barWidth – 2, height);
int labelWidth = labelFontMetrics.stringWidth(names[i]);
x = i * barWidth + (barWidth – labelWidth) / 2;
g.drawString(names[i], x, y);
g.drawString(((int)values[i])+””, x-2, valueY);