Võ Văn Hải's blog

Chỉ có một điều tuyệt đối đó là mọi thứ đều tương đối…

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:

https://vovanhai.files.wordpress.com/2011/11/clip_image0012.png

Sau khi nhấn nút “Character Statitics” ta có hình thống kê như sau

https://vovanhai.files.wordpress.com/2011/11/clip_image003.jpg

Đầ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:https://vovanhai.files.wordpress.com/2011/11/image.png

Chúc bạn thành công!

2 Responses to “Thống kê ký tự trong file và vẽ biểu đồ”

  1. nhưng em strarting xong chay editor ma không chay ra gì hết thầy

  2. 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);

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.