顯示具有 I/O 標籤的文章。 顯示所有文章
顯示具有 I/O 標籤的文章。 顯示所有文章

2021年7月22日 星期四

JAVA IO套件-05 讀檔與計算字數

  上次說要做的練習,讀取英文文字檔案並計數裡面出現的每一個字。

讀取類別:將文字檔案讀取後存成一維陣列,

import java.io.*;
public class ReadAsRaw {
String fileName;
int x;

// 字串讀取方法,就是英文單字,這個方法讀取存成一維陣列。
public String[] readStringFile(String fileName,int x) throws IOException{
this.fileName = fileName;
this.x = x;
int total = 0;
String[] stringArry = new String[x];
if( new File(fileName).exists()) {
BufferedReader fileString = new BufferedReader(new FileReader(fileName));
String line;
while ((line = fileString.readLine()) != null) {
String [] unit = line.split("\\W+"); // 用一個或多個非字母字元分割字串。
int size = unit.length;
for (int i = 0; i < size; i++){
stringArry[total + i] = unit[i];
}
total=total+size;
}
fileString.close();
}
else {
System.out.println("沒有 " + fileName + " 登!登!");
}
System.out.println("總字數:"+ total);
return stringArry;
}

}

字數計算類別:計數丟入的一維字串陣列中的每個單字出現次數。

import java.util.HashMap;

public class WordCount {

public void wordsCount(String[] sentence) {
// TODO Auto-generated method stub
String[] words = sentence ;//sentence.split("\\W+");
//新建一個 HashMap
HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
int j = 0;
for (int i = 0; i < words.length; i++) {
if (hashMap.get(words[i]) == null) {
hashMap.put(words[i], 1); //如果 hashMap 中沒有那個單詞,設定值為 1
}
else { //如果 hashMap 中有這個單詞,則將該單詞的值加 1
hashMap.put(words[i], hashMap.get(words[i]) + 1);
j++;
}
}
System.out.println(" " + j + " 個不同的單字");
for(int i = 0; i < j; i++) {
System.out.println(words[i] + " ; " + hashMap.get(words[i]));
}

}
}

主程式:事先必須準備好一個文字檔於在專案資料夾中,例如 test.txt 。

public class Main {
public static void main(String[] args) throws Exception{

ReadAsRaw rW = new ReadAsRaw();
String nameString = "test.txt";
int guessTotal=313; // 猜總字數,可以大於等於,不能小於真實的字數。
String[] sArry = rW.readStringFile(nameString, guessTotal);

WordCount cW = new WordCount();
cW.wordsCount(sArry);
//System.out.println(cW.);
}
}

結果:因為太長,所我中間省略了,前面單字,後面數字。

總字數:313
有 137 個不同的單字
Quantum  ;  3
mechanics  ;  8
is  ;  4
a  ;  7
fundamental  ;  1

中間略

are  ;  2
restricted  ;  1
to  ;  7
discrete  ;  1

Process finished with exit code 0

  這邊用分號是因為試算表可以用分號當分隔符號,方便大家後續的操作。這個程式還有一件事情我沒有做,那就是排序。暫時懶得寫。最近有其他目標,下次練習應該是一段時間後了。

  為了完成這個練習,我所找到的程式參考來源:https://www.itread01.com/p/1432610.html;另外還有一個別人已經寫好,放在網路上分享的字數統計工具:https://blog.qqboxy.com/2016/06/english-word-analyze.html



2021年7月19日 星期一

JAVA IO套件-04 用物件讀數字

  如同前一篇所說的,我想保持主程式的簡單性,於是我把複雜留給類別,清爽留給主程式。又一次要傳的數字是一大堆,所以方法中宣告一個二維陣列去存數字。然後在主程式中也宣告一個二維陣列去接收其位址(程式碼看起來是回傳陣列給主程式,實際上傳的是陣列的位址)。

將讀到的值存成矩陣的類別:
import java.io.*;
public class ReadAsMatrix {
String fileName;
int x,y;

public int[][] readIntFile(String fileName,int x,int y) throws IOException{
this.fileName = fileName;
this.x = x;
this.y = y;
int[][] intgerArry = new int[x][y];
if( new File(fileName).exists()) {
BufferedReader fileInteger = new BufferedReader(new FileReader(fileName));
String line;
int j=0;
while ((line = fileInteger.readLine()) != null) {
String [] unit = line.split("\\s+"); // 用空格分割字串,並指定給字串陣列。
int size = unit.length;
for (int i = 0; i < size; i++){
intgerArry[j][i] = Integer.parseInt(unit[i]);
}
j++;
}
fileInteger.close();
}
else {
System.out.println("沒有 " + fileName + " 登!登!");
}
return intgerArry;
}
}
主程式:
/* 讀寫整數 */
//import java.io.*;
public class Main {

public static void main(String[] args) throws Exception{

// 宣告 rI 是一個讀取檔案值並存為矩陣的物件。
ReadAsMatrix rI = new ReadAsMatrix();

String nameInteger = "整數檔.txt";
int x=10,y=10; // 行數、列數(直行、橫列)。

// 使用 rI 物件的方法,並將結果的矩陣位址傳給 iArry
int[][] iArry = rI.readIntFile( nameInteger, x, y);


// 展現讀取的陣列數值。
for ( int j = 0; j < x; j++){
for (int i = 0; i < y; i++){
System.out.print(iArry[j][i]+";");
}
System.out.println();
}
}
}

  不看主程式後面展現讀取結果的雙迴圈和註解的話,主程式只用了四行來完成讀取。因為我類別內方法的寫法關係,使用這個程式,x、y 的值必須夠大,太小會出錯,太大則沒有給值的陣列元素會是初始值 0 ,所以如果使我的程式,最好確定檔案的行數與列數。

  如果想讀取的是實數、字串,就必須要改變類別中的方法,並不難。我已經寫好了,但示範的程式碼以簡潔為主,就不放上來了。


  如果想要對 String.Split 有更多理解,這裡:String.Split

  接下來我想做的練習是統計字母、單字,沒想到網路上已經有人做了,這裡:字的統計


2021年7月17日 星期六

JAVA IO套件-03 讀取數字

  這一篇是我想到我以前做研究時最需要的基本能力,可以讀取數字檔案,並對其內容做操作,以完成我們想要的分析。我的書上沒看到這部份的語法教學,似乎這個能力對寫 JAVA 的人來說並非必要,所幸網路上找得到教學,應該做數值分析或統計的人都用得到吧!

  建立專案後,把準備好的 整數檔.txt 放到專案資料夾中,我這次放的是一個十十乘法的值。這次我直接在主程式寫,結果整數檔案必須放在專案的資料內,跟我的第一次不同,卻跟第二次相同,這部份我還想不到理由。以下是十十乘法的值,按圖可放大。

主程式:我使用了和前兩次練習相同的方式讀取文字檔案的每一行,所以如果我的前兩次練習在做什麼都有理解,那其實這次的重點就只有包含我做註解的那一行往下六行而已。

/* 讀整數 */
import java.io.*;
public class Main {

public static void main(String[] args) throws IOException{
String nameInteger;
nameInteger = "整數檔.txt";
if( new File(nameInteger).exists()) {
BufferedReader fileInteger = new BufferedReader(new FileReader(nameInteger));
String line;
while ((line = fileInteger.readLine()) != null) {

String [] unit = line.split("\\s+"); // 用一個或多個空格分割字串,並指定給字串陣列。
int size = unit.length;
int[] intgerRow = new int[size];
for (int i = 0; i < size; i++){
intgerRow[i] = Integer.
parseInt(unit[i]);
}

System.
out.println(intgerRow[1] + " + " + intgerRow[2] + " = " + (intgerRow[1]+intgerRow[2]));
}
fileInteger.close()
;
}
else {
System.
out.println("沒有 " + nameInteger + " 登!登!");
}
}
}

結果:看得出來是可以做數值運算的,所以的確有把讀取到的字串轉換成數字。

2 + 3 = 5
4 + 6 = 10
6 + 9 = 15
8 + 12 = 20
10 + 15 = 25
12 + 18 = 30
14 + 21 = 35
16 + 24 = 40
18 + 27 = 45
20 + 30 = 50

Process finished with exit code 0

  我必須說,以讀取的功能來說, fortran 真的是方便多了。上面那些程式碼如果沒物件導向的基本概念,應該不容易看懂,難怪我當時的學校物理系、化學系是教 fortran 而非 JAVA 了。雖然 fortran 處理數字和讀取檔案容易,不過以未來求職的角度來看,還是其他語言比較有優勢。

  最後,寫這麼多行只為了處理一個檔案,主程式顯得很亂,之後我還是把這些處理方式寫在類別裡面吧!

2021年7月16日 星期五

JAVA I/O 套件-02 基本練習,混合中英歌詞

  上一篇是寫入與讀取的練習,利用相同的方法,我寫了一個把英文歌詞和中文歌詞合在一起的程式,最後會產生一個英中對照的文字檔。這次我選的是 You're gonna go far, kid ,歌詞來源是 https://genius.com/The-offspring-youre-gonna-go-far-kid-lyrics ,我把一些不要的刪掉後,存成文字檔,


然後自己翻譯成中文,


把兩個檔案放在 project 的資料夾內,上一個練習是放在 src 資料夾裡面,這次是放與 src 同位置的資料夾,原因是這一次我打算保持主程式的簡潔,所以複雜的流程放在類別裡面了。那為什麼這麼一來文字檔放的位置就不同了呢?我也不曉得,查了好久才發現這個現象。

混合歌詞的類別:

/* 混合兩份歌詞 */
// 編寫人:Lancelot Cheng
import java.io.*; // I/O 套件是在使用的類別中引入,而非在主程式中引入。
public class Mix2Lyrics {
String name1,name2,name3;

public Mix2Lyrics(String name1, String name2, String name3){
this.name1 = name1; // 要混合的第一份(英文)歌詞檔名。
this.name2 = name2; // 要混合的第二份(中文)歌詞檔名。
this.name3 = name3; // 混合後的檔名。
}

public void mixThem() throws Exception{ // 要記得加 throws Exception
BufferedReader readEng = new BufferedReader(new FileReader(name1));
BufferedReader readChi = new BufferedReader(new FileReader(name2));
String song1;
String song2;
BufferedWriter writeCom = new BufferedWriter(new FileWriter(name3));
while(((song1 = readEng.readLine()) != null) && ((song2 = readChi.readLine()) != null)) {
System.out.println(song1);
System.out.println(song2);
writeCom.write(song1+"\n");
writeCom.write(song2+"\n");
}
readEng.close();
readChi.close();
writeCom.close();
}
}

主程式:

/* 主程式 */
// 編寫人:Lancelot Cheng
public class Main {
public static void main(String[] args) throws Exception{ // 要記得加 throws Exception
Mix2Lyrics uRGonnaGoFar = new Mix2Lyrics
("You're gonna go far, kid.txt", "你會功成名就,孩子.txt","英中對照.txt");
uRGonnaGoFar.mixThem();
}
}

結果:

Show me how to lie, you're getting better all the time
秀給我看你是如何欺騙眾人,你技藝總是越來越好。
And turning all against the one is an art that's hard to teach
讓眾人群起攻擊一個人,那可是一門難以教授的藝術啊!
Another clever word sets off an unsuspecting herd
用另一個聰明的字眼,鼓動毫無戒心的群眾,
And as you step back into line, a mob jumps to their feet
而當你退回人群之中,一群暴徒躁動了起來。


Now dance, fucker, dance man, he never had a chance
現在跳舞吧!混蛋!跳舞人們啊!那個受害者未曾有過機會。
And no one even knew it was really only you
甚至沒有人知道,真正的兇手就只有你!
And now you steal away, take him out today
現在你逍遙法外,讓在受害者在今日失去一切。
Nice work you did, you're gonna go far, kid
幹得好,孩子!你必將功成名就!


With a thousand lies and a good disguise
撒上千百謊言與偽裝成好人,
Hit 'em right between the eyes, hit 'em right between the eyes
痛擊他們的眉心!痛擊他們的眉心!
When you walk away, nothing more to say
當你一走,什麼都沒說,
See the lightning in your eyes, see 'em running for their lives
看看你眼中的閃電,看看他們為了生存而奔跑。


Slowly out of line, and drifting closer in your sight
我慢慢地置身於外,卻飄近你的視野之中。
So play it out, I'm wide-awake, it's a scene about me
所以玩開來吧!我非常清楚,這次輪到我了!
There's something in your way and now someone is gonna pay
你的路上有阻礙,而且有人必須付出代價,
And if you can't get what you want, well, it's all because of me
而如果你不能得到你所要的,哈!那全是因為我!


Now dance, fucker, dance, man, I never had a chance
現在跳舞吧!混蛋,跳舞吧!老兄!我未曾有過機會。
And no one even knew, it was really only you
甚至沒有人知道,真正的兇手其實只有你!
And now you'll lead the way, show the light of day
現在你引領著道路,展現日子的光明
Nice work you did, you're gonna go far, kid, trust deceived
幹得好,孩子!你必將功成名就。信任被欺騙!


With a thousand lies and a good disguise
撒上千百謊言與偽裝成好人,
Hit 'em right between the eyes, hit 'em right between the eyes
痛擊他們的眉心!痛擊他們的眉心!
When you walk away, nothing more to say
當你一走,什麼都沒說,
See the lightning in your eyes, see 'em running for their lives
看看你眼中的閃電,看看他們為了生存而奔跑。


Now dance, fucker, dance, he never had a chance
現在跳舞吧!混蛋!跳舞!那個受害者未曾有過機會。
And no one even knew, it was really only you
甚至沒有人知道,真正的兇手就是你!
So dance, fucker, dance, I never had a chance
所以跳舞吧!混蛋,跳舞吧!我未曾有過機會。
It was really only you
真正的兇手其實只有你!


With a thousand lies and a good disguise
撒上千百謊言與偽裝成好人,
Hit 'em right between the eyes, hit 'em right between the eyes
痛擊他們的眉心!痛擊他們的眉心!
When you walk away, nothing more to say
當你一走了之,什麼都沒說,
See the lightning in your eyes, see 'em running for their lives
看看你眼中的閃電,看看他們為了生存而奔跑。


Clever alibis, Lord of the Flies
巧妙的不在場證明,蒼蠅王!
Hit 'em right between the eyes, hit 'em right between the eyes
痛擊他們的眉心!痛擊他們的眉心!
When you walk away, nothing more to say
當你一走了之,什麼都沒說,
See the lightning in your eyes, see 'em running for their lives
看看你眼中的閃電,看看他們為了生存而躲避。

Process finished with exit code 0

產生的檔案~~


如果想聽這首歌的話,網址:https://www.youtube.com/watch?v=ql9-82oV2JE



JAVA I/O 套件-01 寫入與讀取文字

  為了方便其見,我把兩個範例寫在一起~~

主程式:

// 使用輸入與輸出套件
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {

// 輸出文字檔案
BufferedWriter writeSomethings = new BufferedWriter(new FileWriter("我是藍斯洛特.txt"));
writeSomethings.write(" 網球場上 \n\n 詐欺師!\n");
writeSomethings.write("今年我要拿四個大滿冠!\n");
writeSomethings.close(); // 關閉串流。
// 執行後, src 檔案夾內就會出現 我是藍斯落特.txt 的文字檔,

// 讀取文字檔案,先在 src 資料夾內準備一個 txt 文字檔,
if(new File("口是心非.txt").exists()) {
BufferedReader readSomething = new BufferedReader(new FileReader("口是心非.txt"));
String song;
while ((song = readSomething.readLine()) != null)
System.out.println(song);
readSomething.close();
}
else {
System.out.println("找不到檔案喔!");
}
}
}

結果:

張雨生

口是心非

作詞:張雨生
作曲:張雨生
編曲:Koji Sakurai

口是心非 你深情的承諾都隨著西風飄渺遠走
癡人夢話 我鍾情的倚托就像枯萎凋零的花朵
星火燎原 我熱情的眼眸曾點亮最燦爛的天空
晴天霹靂 你絕情的放手在我最需要你的時候

於是愛恨交錯人消瘦 怕是怕這些苦沒來由
於是悲歡起落人靜默 等一等這些傷會自由

口是心非 你矯情的面容都烙印在心靈的角落
無話可說 我縱情的結果就像殘破光禿的山頭
渾然天成 我純情的悸動曾奔放最滾燙的節奏
不可收拾 你濫情的拋空所有晶瑩剔透的感受

Process finished with exit code 0

口詞心非的歌詞檔案取自:https://mojim.com/twy100199x10x2.htm