總網頁瀏覽量

2013年5月31日 星期五

URL

try{

URL u=new URL("http://www.google.com/xxx/conan.html");
System.out.println(u.getProtocol());//http
System.out.println(u.getHost());//www.google.com
System.out.println(u.getPort());//URL若沒有埠號則回傳-1
System.out.println(u.getFile());// 回傳/xxx/conan.html

}catch(MalformedURLException e){

System.out.println("Error 404");

}






取得主機ip與名字---InetAddress

public static void main(String[] args)  {
try{
//註解是列印的結果

// InetAddress adr = InetAddress.getLocalHost();
//向主機取得InetAddress物件
//InetAddress adr = InetAddress.getByName("google.com");//google.com/74.125.31.100
//向網域名稱取得InetAddress物件

byte[] ip={8,8,8,8};
InetAddress adr = InetAddress.getByAddress(ip);
//google-public-dns-a.google.com/8.8.8.8
//以ip取得主機名稱

System.out.println(adr.getHostAddress());
System.out.println(adr.getHostName());
System.out.println(adr);

}catch(UnknownHostException e){

System.out.println("Error 404");

}
}

2013年5月30日 星期四

邏輯運算子與位元運算子

邏輯運算子: &&

4 && 5 會comple error
運算元必須是邏輯判斷式、true、false


位元運算子: &

4 & 5 相當於 100 and 101
結果等於4


應用在條件判斷式
if((num2>100)&(--num1>0))
如果num2>100為false那麼 num1不會進行運算

if((num2>100) && (--num1>0))
那麼即使num2>100為false
--num1會進行運算再作條件判斷



2013年5月26日 星期日

Edittext

EditText
執行程式會一直觸發setOnKeyListener事件
我們可以override setOnKeyListener並實作傾聽者OnKeyListener

setOnKeyListener(new OnKeyListener(){
public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
return false;
}});


arg1:按下enter會回傳67 按下刪除建會回傳66
arg2:按下的動作:Action_Down,Action_Up

arg2.getAction()取得使用者對按鈕做什樣動作。
arg2.ActionDown
arg2.Action_Up


可以在XML就幹好的事情
1.顯示預設的文字
android:hint
設定Edittext預設的顯示文字
2.限制輸入文字的長度
android:maxLength="20"
3.限制只能輸入電話號碼
android:phoneNumber="true"
4.限制輸入的數字
android:digits="123"
如此一來只能輸入1或2或3














2013年5月23日 星期四

開啟瀏覽器或導向網站

按下按鈕讓畫面跑到我的網站:

利用Intent物件來實作


1.
在res/values底下新增一個array.xml
記得要打上name,name設定為arrays
新增element選擇String arrays
之後新增四個item,values分別為
android.intent.action.VIEW
android.intent.action.WEB_SEARCH
android.intent.action.CALL
android.intent.action.DIAL

2.
在MainActiviry.java

ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,R.array.arrays,android.R.layout.simple_spinner_item);
宣告陣列配接器,this表示該陣列配接器為本activity所用
R.array.arrays表示採用res/value之下的array.xml裡面名稱arrays的String arrays
android.R.layout.simple_spinner_item表示這個陣列配接器用在spinner元件上

adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//將array.xml的項目與adapter連接

spinner.setAdapter(adapter);
//將adapter安置在spinner


3.宣告Intent物件寫在Button onClick裡面

Intent intent =new Intent(spinner.getSelectedItem().toString(),Uri.parse(edittext.getText().toString());
宣告Intent物件,new Intent(採取的動作 , Url或Uri);
例如:(android.intent.action.VIEW,http://www.google.com)
執行時會去開啟瀏覽器並且為google的網頁
startActivity(intent);

2013年5月19日 星期日

inhon g1 刷機筆記

本篇紀錄安裝過程漏掉的事情,詳細過程請參考網路上圖文教學:

刷機就是重灌整個手機系統的意思。

step一、事先必須準備額外記憶卡一張,裡面存放:

1.刷機之前的自行備份資料.backup檔案
(如何備分參考網路圖文教學)

2.放壓縮檔Taiwan101_InHon-G1_JB_V.01-4,其實這是映像檔(iso,img類型的檔案)。

3.放壓縮檔Taiwan101_SuperSU_Pro_v1.03
(這是開啟root權限的壓縮檔)



step二、安裝驅動程式
請參考taiwan101安裝驅動程式步驟。
如果之前跟我一樣有從別的地方安裝驅動程式,flash tool也抓不到手機
那就試著安裝taiwan101的驅動程式吧(舊的驅動程式不用刪掉)


通常flash tool按下download之後,電腦螢幕底下長條沒在跑就代表電腦沒抓到手機

檢查有沒有安裝成功步驟如下:
在手機關機狀態時,USB插入電腦後,同時按下"開機鍵"+"降低音量按鈕"
手機會開機進入Factor Mode,這時電腦會開始偵測手機裝置。
如果有MT65xx android phone這個項目那就表示驅動程式安裝成功的。


其餘跟網路上教學一樣

VM ubuntu可以上網 ping不到ip

關掉實體電腦的共用網路
之後再研究有沒有辦法不用關掉共用網路的方法

ubuntu10.10已經停止支援了orz

2013年5月18日 星期六

linux權限

sudo passwd root
設定root密碼,啟用root帳號
如果沒有做這一步
su -   不會成功的


操作圖形介面建立帳號
1./etc/passwd    在這裡新增帳號
2./etc/shadow   在這裡新增密碼
3./home/XXX    複製一份home底下的資料夾,更改檔名


刪除帳號 sherlock
sudo userdel sherlock

linux指令:新增檔案目錄、看工作程序、硬碟、CPU資訊


man(manual)查指令手冊
man pwd
查pwd的用法



sudo halt關機,必定用root權限執行

pstree看程序執行狀況,可以看到根節點為init

init重新開機


ps可以用來看apache有沒有安裝成功
ps看預設終端機程序
ps a 看所有終端機
ps w 看誰登入我的電腦
ps axu  以user觀點看誰在執行程序
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.3  0.0   2888  1652 ?        Ss   05:28   0:02 /sbin/init
conan     1603  0.0  0.1   8648  3092 ?        S    05:28   0:00 /usr/lib/gvfs/g


~$字眼的表示user在Home目錄
conan@ubuntu:~$

pwd列印使用者正在哪個目錄
/home/kaibals



ls / /home/kaiba/ns-allinone-2.34/
看根目錄以及看ns-allinone-2.34底下的檔案與資料夾



ls -l 詳細列出檔案與資料夾的讀寫刪權限以及名字以及佔記憶體大小建立日期


- rw- r-- r--  1 conan kaiba    0 2013-05-18 06:55 Iam
d rwx r-x r-x  3 conan kaiba 4096 2013-05-18 06:50 iii/
第一個為-表示檔案型態 rw-擁有者權限(root或建立檔案的人) r--群組權限 r--其他權限
第二個為d表示為目錄型態

如果mkdir -m 777 directory1
則會建立權限全開的directory1目錄
777表示 111 111 111 以二進位表示權限的開關



df(disk file)看硬碟狀況
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda1             29640780   9177428  18957664  33% /
none                   1024860       204   1024656   1% /dev
none                   1030476       240   1030236   1% /dev/shm
none                   1030476       100   1030376   1% /var/run
none                   1030476         0   1030476   0% /var/lock

/dev/sda1意思是
s:skashi
d:disk
a:第一顆硬碟

df -h   (以給人看得格式顯示硬碟狀況

Filesystem            Size  Used Avail Use% Mounted on
/dev/sda1              29G  8.8G   19G  33% /
none                 1001M  204K 1001M   1% /dev
none                 1007M  240K 1007M   1% /dev/shm
none                 1007M  100K 1007M   1% /var/run
none                 1007M     0 1007M   0% /var/lock



du(directory use)看當下目錄裡所有檔案占用的大小
du /   看根目錄使用多少容量(等於看該系統共用了多少容量)


free -m  看記憶體使用大小  -m意思是單位為MB
             total       used       free     shared    buffers     cached
Mem:          2012        599       1413          0        148        164
-/+ buffers/cache:        287       1725
Swap:         1308          0       1308



cat(content at)
cat /路徑/檔案   看某路徑某檔案內容
cat /proc/cpuinfo   看CPU狀態以及CPU品牌、幾核心
結果:
processor : 0
vendor_id : AuthenticAMD
cpu family : 16
model : 5
model name : AMD Phenom(tm) II N930 Quad-Core Processor
stepping : 3
cpu MHz : 1995.050
cache size : 512 KB
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 5
wp : yes


根目錄架構:

dev:cpu,disk資料夾都在這
etc:系統組態檔案,系統打算重灌必須備份。系統調校地方。帳號密碼存放在etc/shadow裡面
資料夾bluetooth,calendar,font,firefox,cron.hourly,corn.weekly,gnome
通通在這
lib:相當於windows的system32,一堆.so(share object)檔案,是linux的.dll檔
init,firmware,linux-sound-base資料夾都在這

lost-found:不當使用檔案遺失片段會放這裡,要以root開
mnt:掛載額外裝置放這裡(usb之類的)
opt:放第三方協力軟體的目錄  ex:綠色軟體
root:相當於windows的administrator,要以root開
sbin(system bin):系統管理員專用的bin 一堆exe檔案
srv(service):對外公開的服務 ex:www,ftp
usr:相當於windows的program file,放安裝的應用程式
裡面資料夾千奇百怪有C++,game,sbin,awk
預設的應用程式好像通通放這
var(variable):有關系統變動頻繁的檔案放這裡。
log,mail,spool都在這

一次建立兩個資料夾
mkdir dir1 dir2
一次建立多個資料夾
mkdir dir{1..9}
只有兩個點喔!多一個點只會建立一個名稱為dir{1...9}的資料夾喔

建立2*4個資料夾
mkdir fold{a..b}_{1..4}

mkdir aaa/bbb/ccc
如果沒有aaa與bbb的話會無法建立ccc
因為沒有parent所以要
mkdir -p aaa/bbb/ccc
p:parent的意思
要有老爸才有兒子

新增檔案
touch filename(摸出檔案)
本質上是改變檔案時戳,新建檔案只是順便

stat filename查看檔案的屬性狀態




複製檔案
cp  filename  directoryname



如果要將整個目錄複製到另一個目錄要加上參數-r
cp -r dir1 dir2
如此一來dir1目錄以及內容整個複製到dir2

移動檔案


將檔案file1 移動到tmp/dir1並改名為ddddd
 mv file1 /tmp/dir1/ddddd

同一目錄移動檔案只會將檔案改名
mv file1 file2
如果目錄已經有file2會將原本的file2砍掉





2013年5月17日 星期五

ShellScript

chmod +x run-VMCA.sh
改變檔案權限,使檔案可執行+x



#
#    VMCA = 0, NMCS = 1, NALM = 2, AMACAD = 3 , VMACA = 4
#pro = 0 1 2 3 4



#sp = 15 20 25 30 35
#sp is speed
#represent for different scenario
#ex:scenario/freeway_200nodes_20km_$sp.tcl




DATE=`date +%F-%H-%M`
//抓取日期與時間

FILE1=Analys_AMACAD/CHlifetime/"AMACAD-"$DATE"-avgCHlifetime.txt"
FILE2=Analys_AMACAD/CMlifetime/"AMACAD-"$DATE"-CMlifetime.txt"
#FILE3=VMCA/"VMCA-"$DATE"-.txt"
#FILE4=VMCA/"VMCA-"$DATE"-CMlifetime.txt"


if [ ! -d Analys_AMACAD ]
then
    mkdir Analys_AMACAD
fi
//fi表示 if then敘述結束的意思


#echo $DATE > $FILE1
#echo $DATE > $FILE2
#echo $DATE > $FILE3
#echo $DATE > $FILE4


for pro in 3
do

case $pro in
0) proto="VMCA";;
        1) proto="NMCS" ;;
        2) proto="NALM" ;;
        3) proto="AMACAD" ;;
        4) proto="VMACA";;
 
    esac
//同理 switch case結束

//以for loop跑不同移動劇本檔案
for sp in 15 17.5 20 22.5 25 27.5 30 32.5 35
do

echo "$pro"
#rm $prto-headlifetime.txt
echo "../ns freeway.tcl $proto scenario/freeway_200nodes_20km_$sp.tcl"
../ns freeway.tcl $pro scenario/freeway_200nodes_20km_$sp.tcl
//採用$pro協定以及,scenario底下的freeway_200nodes_20km_$sp.tcl移動劇本檔執行freeway.tcl


    cp $proto-headlifetime.txt Trace/$proto/$proto-CH-speed-$sp-Date-$DATE.txt
       cp $proto-memberduration.txt Trace/$proto/$proto-CM-speed-$sp-Date-$DATE.txt
//不論跑任何協定C語言輸出的檔名都一樣
//將C語言輸出的結果,複製到以協定名稱命名的檔案

rm $proto-headlifetime.txt
rm $proto-memberduration.txt
//將C語言跑出的檔案刪掉

echo "awk -f chlifetime.awk $proto-headlifetime.txt............."

awk -v speed=$sp -f chlifetime.awk Trace/$proto/$proto-CH-speed-$sp-Date-$DATE.txt >> $FILE1
//執行awk檔案針對C語言輸出的數據做加總與平均運算


echo "awk -f memberifetime.awk $proto-memberlifetime.txt............."

awk -v speed=$sp -f memberlifetime.awk Trace/$proto/$proto-CM-speed-$sp-Date-$DATE.txt >> $FILE2




#awk -v speed=$sp -f chlifetime.awk Trace/$proto/$proto-speed-$sp-Date-2012-06-17-15-37.txt >> $FILE1


done


done

2013年5月15日 星期三

MySQL::illegal mix of collations (latin1_bin implicit) and (utf8_general_ci coercible)

將舊版的MySQL(被Oracle併購之前的)資料移植到新版的MySQL發生問題

在下達指令
select * from table where code='哈';

發生
illegal mix of collations (latin1_bin implicit) and (utf8_general_ci coercible)
錯誤訊息


案發現場狀況:

資料庫建立時候我原本採用latin1編碼
因此只有character_set_database 為 latin1

其餘都是utf8或binary

show variables like'%charact%';
顯示環境變數如下:
character_set_client     | utf8
character_set_connection | utf8
character_set_database   | latin1  //資料庫原本以latin1建立的
character_set_filesystem | binary
character_set_results    | utf8
character_set_server     | utf8
character_set_system     | utf8





解決方式:
目前先將client ,connection,results,server通通設定為latin1
就OK了。
有空再一個一個測試到底是哪個變數出問題...........


設定如下:
character_set_client     | latin1
character_set_connection | latin1
character_set_database   | latin1  //資料庫原本以latin1建立的
character_set_filesystem | binary
character_set_results    | latin1
character_set_server     | latin1
character_set_system     | utf8

Java Web相關

Servlet是Java 裡面的class,可以由單一process中的多個執行緒來執行個別的的server程式,
Servlet是ServletContainer一部分。

JavaBean
CustomerTag
讓元件方便reuse

Http的stateless:
意思是HTTP無狀態協定:在HTTP1.0架構下,client端每一次請求都必須重新向server連線一次。
例如:向youtube每點一次影片或下載一次圖片就要重新與server連線一次。
server也無法辨認不同的連線是否來自同一client

stateless的問題可以由cookie  session,url-rewriting解決


URI:Uniform Resource Identifier
URL=通訊協定+主機位置+URI
URI:指向資源所在路徑
URI是URL自古以來神聖不可分割一部份


2013年5月11日 星期六

C語言回顧

C語言沒有string
但是C++有不過string似乎非C語言的關鍵字

#include<stdio.h>
以#開頭的指令在程式編譯前會由前處理器先行處理。

cout << "ByeByeWorld" << endl;
//相當於printf("ByeByeWorld\n");
將ByeByeWorld輸出到顯示器上,並將指標cursor移到下一行
這種訊息叫做提示prompt

endl 表面上是換行字元
事實上是指示CPU將記憶體中的資料送到輸出資料流中(ex:顯示器 或某檔案)

cin >> variable;
//相當於scanf("%d",&variable);


C語言的if-else跟java有點不一樣
if(name=1)可以編譯過且可以執行


函數:
分三部分函數宣告、函數定義、函數呼叫

void main(){
editdistance(num);

return 0;
}

int editdistance(int n){
int x;
return x;
}


傳直呼叫:editdiatance函數被呼叫時,引數num先複製到記憶體的stack區塊,接著將n放進stack,接收num的值,進行運算完之後return x;將x複製一份到stack之內,最後main再將stack的結果複製回來。


reference參照:
int N =5;
int& M=N;
M是N的參照,alias
有點像java的 String str ="kkk";  String str2=str;
M變數成為N的綽號
更改M會改變N
更改N會改變M
參照宣告時要初始化否則會發出警告

應用:swap function

傳參照使用時機如果不是以下三種狀況最好不要用,避免無意間更改變數值
1.傳遞過去的引數必須改變
2.傳回兩個以上的值
3.有大量數值需要傳遞,如果採用傳直呼叫,將耗費大量時間在數值複製上
例如引數為大量陣列的情況


陣列:
一維陣列:vector
二維陣列:matrix
三維陣列:tensor

陣列宣告事先宣告大小
const int SIZE =5;
double Pressure[SIZE];
陣列名稱Pressure內存陣列起始位置
可以直接function(Pressure);
傳遞參數呼叫function,function使用的陣列跟main使用的陣列是同一個而不是複本
這是傳址呼叫,在function所做的更動作用在原本陣列身上

sizeof(變數);回傳變數所占記憶體大小
其實是變數實際所站的空間與一個char所占空間比值

陣列大小必須在編譯階段就可以確定的整數
不可以宣告成以下這樣
int a=9;
float farr[a];

指標:


double A = 2.5;
double* pF; //宣告pF,變數型態為"指向double變數的指標型態"
pF= &A;//pF儲存A的記憶體位置,指標pF指向變數A
cout<<*pF<<endl;
//印出pF指向的變數內容


注意double*的指標不可以指向int變數
(編譯器不會自動convert)
也就是說double限制住指標可以指向那些型態變數

記住double* pF;
pF資料型態是double*


double x;
x =*pF;
將pF指向的變數內容存到x裡面


*以及&在宣告時候的意義是告知變數型態而不是取址取值運算
double* p;
double &y=x;

陣列指標:
一個指標存放陣列的位置(也等於array[0]的位置)。


const int size =5;
double V[size]={55.66,11.22,33.44,77.88,99.11};
double* pv=V;
//pv存放陣列的位置
int i=0;
for(i=0;i<size;i++){
cout<< *(pv+i)<<endl;
//指標加1等於陣列位移一格
}

V本身就是一個指標,存放陣列的位置
所以for loop也可以寫
*(V+i)也OK啦



二維陣列的指標
利用指標存取二維陣列:
指標的指標

double B[Row][Col]= {{1.8,4.9,6.8},{6.2,4.1,6.3}};
*B表示存取B[0]也就是陣列B的位置
*B+1同等於*(B+1)先加再取,存取B[1]的元素
**B表示存取B[0][0]的位置
**(B+1)存取B[1][0]同等於*(*(B+1))


int i,j;
for(i=0;i<Row;i++){
for(j=0;j<Col;j++)
{

cout << *(*(B+i)+j) << endl;

}

}

指標參數(傳址呼叫)

X=func(&x,&y);
int func(int*  x, int*  y)

回憶:傳參照呼叫
X=func(a,b)
int func(int& x,int& y)
一旦設定指向參考的變數之後,這個參考就無法再指向其他的變數


6.指標未設定初值不可以這樣寫

int *ptr;
*ptr=2;
//會compile error

7.
可以直接將字串存進指標變數
char* ptr="118";
cout<< ptr;//直接印出字串

int x=112;
 int* num=112;//錯誤寫法,只有字串才可以這樣用
cout<< num;

8.
C++的NULL要大寫,NULL是常數定義為 ((void*)0)


9.不論指標指向哪種資料型別記憶體空間
,指標變數大小一律為4bytes  。


10.指標為何要宣告資料型別?
因為程式要透過指標變數所宣告的資料型別,判斷指標所指向的變數是哪種類型。
這樣編譯器可以知道指標的索引增減該移動多少位元
例如:double指標變數指向double 陣列。當變數+1時候邊義器就知道要移動八位元組才會得到下一筆double資料。


所以指向不同型別變數的指標變數不可以互相指派
int x=19;
double* ptr =&x;
這樣ptr往下一筆存資料index會移動八位元組
而int只有四個位元組
ptr存到第三筆資料去了

11.
可以透過強制型別轉換:讓double* 指標變數可以指向int*指標變數

int i=10;
int* ptr_i=&i;
double* ptr_d;
ptr_d=(double*)ptr_i;

cout<<"ptr_i ="<< ptr_i <<endl;
cout<<"*ptr_i="<<*ptr_i<<endl;

cout<<"ptr_d ="<< ptr_d <<endl;
cout<<"*ptr_d="<<*ptr_d<<endl;//印出奇怪的浮點數字   因為編譯器用8bytes解析
cout<<"*((int*)ptr_d)"<< *((int*)ptr_d)<<endl;//印出正確的數字  因為編譯器用4bytes 解析


12.
不定型别指標變數宣告void *
當宣告指標變數時,還不確定指標所指向的記憶體空間,將儲存哪種資料型別時候,可以將它宣告為
不定型別的指標void*


13.不定型別指標變數的強制轉換

int i=10;
int* ptr_i=&i, *ptr_i1=NULL;
void* ptr_void;

ptr_void=ptr_i;//不定型別可以指向各類型別指標

ptr_i1=(int*)ptr_void;
//各類型別指標要指向不定型別必須強制轉型

cout<<&i<<endl;
cout<<ptr_void<<endl;
cout<<ptr_i<<endl;
cout<<ptr_i1<<endl;
//以上四個值都一樣,那三個指標都指向i了
cout<< *(int*)ptr_void<<endl;
//務必再次轉換因為電腦不記得剛剛有轉過型別,否則會錯誤




Eclipse部署C語言環境

1.help→install new software→add→貼上CDT官網
安裝CDT(C++ Develope Tool)
包含一堆C語言的套件

2.
安裝編譯器
下載MinGW
安裝c compile,c++ compile,msys,最底下項目也勾
一共四個項目
之後
設定環境變數
C:\MinGW\bin
C:\MinGW\msys\1.0\bin

C:\MinGW
C:\MinGW\msys\1.0


加入path

如此一來可在cmd
下gcc  g++ awk指令
如同在linux一樣


eclipse方面window→properties→C/C++→build→makefile edit→settings
新增C:\MinGW\bin

window→properties→C/C++→New CDT Project Wizard→Makefile project→binary parser
只有PE windows parser 要打勾

最後新增C++ project→選擇MinGW gcc→finish

大功告成 測試。
之前一直沒安裝成功 出現library not found
推測原因:沒有做紅色字體步驟或者新增專案沒有include資料夾的關係。
且要先clean project之後再build project


新增c++ project時候,eclipse會要開發者選擇編譯器,要選編譯器MinGW
否則想破頭也無法解決binary not found喔

專案之中要有Binaries這項目

eclipse安裝C語言環境真麻煩
編譯過程有點像是之前在ubuntu run C一樣


2013年5月4日 星期六

計算機(附打地鼠)


發想:
小學時候買過一種計算機
除了計算功能之外可以玩遊戲
其中有一款是打地鼠遊戲
因為找不到有程式這款遊戲
所以就寫個計算機程式當作練習
也順便實現這遊戲


本遊戲採用swing元件來實作

整個畫面是BoredLayout
North區塊放label;Center區塊放JPanel物件
JPanel採用GridLayout


第一個檔案UI.java

/*
 * 此檔專用來版面配置
 *
 * */

package EraseNum;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class UI extends JFrame {

static UI windows = new UI();
static Container cp = windows.getContentPane();
// static JButton game = new JButton("打地鼠");
// static JLabel label= new JLabel("這是Label");
static JTextField textfield = new JTextField();
static JPanel jpanel = new JPanel();
static JButton[] buttons = new JButton[25];

UI() {

}

public static void main(String[] args) {

windows.setTitle("Erase Number");
windows.setSize(550, 500);
cp.setLayout(new BorderLayout(10, 10));
// 10是水平與垂直間距
cp.setBackground(Color.pink);

// ======TextBox=====

Font font = new Font("新細明體", Font.ITALIC + Font.BOLD, 16);
Font lb_font = new Font("新細明體", Font.ITALIC + Font.BOLD, 58);
// label.setFont(lb_font);
// cp.add(label,BorderLayout.NORTH);
// BorderLayout.North不寫的話預設放在中間且填滿整個螢幕

// 靠右對其
textfield.setHorizontalAlignment(JTextField.RIGHT);
textfield.setFont(lb_font);
textfield.setEditable(false);
cp.add(textfield, BorderLayout.NORTH);

// ======TextBox=====

// =======Panel放置GridLayout
jpanel.setLayout(new GridLayout(5, 5, 5, 5));

String[] Button_Name =
{ "score", "GAME", "Back", "Calcu", "Level",
"7", "8", "9", "/", "sqrt",
"4", "5", "6", "*", "%",
"1", "2","3", "-", "pow",
"0", ".", "=", "+", "-/+" };

ButtonActionListener listener = new ButtonActionListener();

for (int i = 0; i < 25; i++) {
buttons[i] = new JButton(Button_Name[i]);
buttons[i].setFont(font);
buttons[i].setName(Button_Name[i]);
buttons[i].setEnabled(true);
// 設定按鈕可不可以按
buttons[i].addActionListener(listener);
// 事件傾聽者向各位按鈕註冊
jpanel.add(buttons[i]);

}
cp.add(jpanel);

// =====JPanel=======
windows.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
windows.setVisible(true);

}

}


第二個檔案:Mole.java



/*
 * 此檔案是打地鼠的程式運作
 *
 * */


package EraseNum;

public class Mole implements Runnable {

private String txtNumber;
private int Number;
private boolean isContinue = true;
// 因為thread不能重新start所以自行宣告method多加一層迴圈了

private int score = 0;
private int level = 1;
private int sleep = 1700;
private int life = 3;

@Override
public void run() {

while (true) {
while (isContinue) {
txtNumber = UI.textfield.getText();
Number = (int) (Math.random() * 10);

UI.textfield.setText(txtNumber + Integer.toString(Number));

try {

Thread.sleep(sleep);
} catch (InterruptedException e) {

e.printStackTrace();
}

if (UI.textfield.getText().length() == 12) {
isContinue = false;
}

}// isContinue
}// true

}

public void terminate() {

isContinue = false;

}

public void restart() {

isContinue = true;

}

public boolean isGameover() {

return isContinue;
}

public void addscore() {

int length = UI.textfield.getText().length();

switch (length) {
case 0:
case 1:
case 2:
case 3:
score = score + 100 * level;
break;
case 4:
case 5:
case 6:
score = score + 80 * level;
break;
default:
score = score + 60 * level;
break;
}

UI.buttons[0].setText(Integer.toString(score));
}

public void levelup() {
if (score > 150000) {
level = 10;
sleep = 400;
UI.buttons[4].setText("Level:"+Integer.toString(level));

} else if (score > 70000) {
level = 9;
sleep = 500;
UI.buttons[4].setText("Level:"+Integer.toString(level));

} else if (score > 45000) {
sleep = 600;
level = 8;
UI.buttons[4].setText("Level:"+Integer.toString(level));

} else if (score > 30000) {
sleep = 700;
level = 7;
UI.buttons[4].setText("Level:"+Integer.toString(level));

} else if (score > 15000) {
sleep = 800;
level = 6;
UI.buttons[4].setText("Level:"+Integer.toString(level));

} else if (score > 10000) {
sleep = 900;
level = 5;
UI.buttons[4].setText("Level:"+Integer.toString(level));

} else if (score > 5500) {
sleep = 1000;
level = 4;
UI.buttons[4].setText("Level:"+Integer.toString(level));

} else if (score > 3000) {
sleep = 1300;
level = 3;
UI.buttons[4].setText("Level:"+Integer.toString(level));

} else if (score > 1000) {
sleep = 1500;
level = 2;
UI.buttons[4].setText("Level:"+Integer.toString(level));

} else {
sleep = 1700;
level = 1;
UI.buttons[4].setText("Level:"+Integer.toString(level));
}

}

public void  initialScore(){
score=0;
sleep=1700;
}


}


第三個檔案 ButtonActionListener.java


package EraseNum;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;

public class ButtonActionListener implements ActionListener {

private boolean isPlaying = false;
private boolean isCalculator = true;

Mole mole;
Thread thread;

@Override
public void actionPerformed(ActionEvent e) {

JButton btn = (JButton) e.getSource();
// 取得事件來源物件
String str = btn.getText();
String str2 = btn.getName();
// 如果沒有setName會回傳null喔
// 到底要用getText還是getName呢?

// 進入打地鼠遊戲
if (str.equals("GAME")) {
isCalculator = false;
isPlaying = true;

UI.buttons[4].setText("Level:"+1);
UI.buttons[0].setText("分數:0");

if (thread == null) {
//初次執行遊戲
UI.textfield.setText("");// 清空JTextfield
mole = new Mole();
thread = new Thread(mole);
thread.start();
// JTextField自動跑出數字
// start()? Thread()?
// 按下數字鍵會削掉數字

} else {
//重啟遊戲
//因為執行緒不可以再次.start()
//所以自己寫method解決掉吧
UI.textfield.setText("");
mole.initialScore();

mole.restart();
}

return;

}

// 計算機功能
if (str.equals("Calcu")) {
isCalculator = true;
isPlaying = false;

if (thread != null) {
mole.terminate();
thread = null;

}

UI.textfield.setText("0");
return;

}

if (isCalculator) {

Calculator(str);

} else {

EraseNumberGame(str);

}

}

public void Calculator(String str) {

// 按下小數點
if (str.equals(".")) {

String Jtxt = UI.textfield.getText();
if (!Jtxt.contains(".")) {
// 小數點只能出現一個
UI.textfield.setText(UI.textfield.getText() + str);
return;
}

}

// 加上負號
// if (str.equals("+/-")) {
//
// Game.textfield.setText(Game.textfield.getText() + str2);
// return;
//
// }

// 按下數字鍵
for (int i = 0; i < 10; i++) {
if (str.equals(Integer.toString(i))) {

String Jtxt = UI.textfield.getText();

if(Jtxt.length()==1 && Jtxt.charAt(0)=='0'){
UI.textfield.setText(str);
}
else{
// 沒有append method
UI.textfield.setText(UI.textfield.getText() + str);
// 做成append效果

}

return;
}
}

}

public void EraseNumberGame(String str) {
// 遊戲結束嗎
if (mole.isGameover()) {
// 按到哪個數字啊
for (int i = 0; i < 10; i++) {
if (str.equals(Integer.toString(i))) {
// JTextField的字串不可以空字串,否則會outofboundexception
if (UI.textfield.getText().length() > 0) {
// 如果textfield第一個字元跟玩家按的數字鍵一樣
if (String.valueOf(UI.textfield.getText().charAt(0))
.equals(Integer.toString(i))) { // 按下的數字鍵是textbox第一個字
// System.out.println(UI.textfield.getText().substring(1));
// 刪掉第一個數字
UI.textfield.setText(UI.textfield.getText()
.substring(1));

mole.addscore();
mole.levelup();

}
}
return;
}
}
}

}

}



Java UI2(swing)



swing是awt加強版。awt的元件都可被swing替代,swing改善awt耗費系統資源與介面醜陋的問題。

swing所有的元件都直接或間接繼承自java.awt.Container類別。

java並不是將物件放在JFrame這一層而是放在ContentPane這層
因此將物件放到視窗之前必須使用Container getContentPane();
method取得視窗容器


注意:
Container有設定Layout的話,Button,Lable等元件的大小、位置設置也會由layout管理。
也就是說layout除了版面配置也會對button,lable的設定做限制
BorderLayout裡面的元件不可以自己setSize設定大小


1.準備JFrame視窗設定大小與標題

import javax.swing.JFrame;

class GameWindow extends JFrame

GameWindow  windows = new GameWindow();
//如果宣告static GameWindow windows=new GameWindow();
//在建構子不可以用windows.setTitle()之類的method
//也許是在new時候還沒有配置記憶體給windows給他
//還沒初始化成功

//Œ–利用static宣告JFrame物件,不要在建構式裡面利用類別變數設定初值
//因為類別變數在執行時才會配置記憶體


windows.setTitle("JFrame視窗標題");
windows.setSize(550,500);
windows.setDefaultCloseOperation(JFrame.EXIST_ON_CLOSE);
windows.setVisible(true);


swing的JFrame視窗比awt複雜,swing視窗包含多個層級,Top level container,root pane , layered pane ,glass pane,每個層級都有特定的功用。
其中以content pane最常用,因為swing的物件幾乎放在content pane這層級。
一開始new 出的JFrame屬於Top level container層級
JFrame繼承自awt的Frame類別因此JFrame可以用Frame的method。

JFrame執行後如果按下關閉視窗X按鈕,JFrame仍會停留在記憶體
因此務必要加上

windows.setDefaultCloseOperation(JFrame.EXIST_ON_CLOSE);
告訴JFrame視窗關閉時候記憶體也要關閉JFrame
否則預設Hide_ON_Close,只是隱藏視窗而已




2.取得ContentPane並設定Layout

import java.awt.Container;
Coantainer cp=windows.getContentPane();//取得視窗容器
cp.setLayout(new FlowLayout());
cp.setBackground(Color.pink);

ContentPane物件相當於awt的Frame
設定Layout種類.setLayout(Layout物件);
設定背景顏色.setBackground(Color.pink);
皆在ContentPane


3.將物件放到ContentPane裡面

//Button game = new Button("打地鼠");
//會出現亂碼,即使workspace以及project property設定為UTF8
//run configuration→common→encoding設定UTF8也一樣
JButton game = new JButton("打地鼠");
//用JButton就OK了
cp.add(game);



4.
GridLayout附加元件順序是由左而右 由上而下





static Game windows = new Game();
static Container cp = windows.getContentPane();
static JButton game = new JButton("打地鼠");
static JLabel label= new JLabel("這是Label");
static JPanel jpanel = new JPanel();

Game(){
// windows.setTitle("Erase Number");
//windows.setSize(550,500 );
// windows.setVisible(true);


}

public static void main(String[] args) {

windows.setTitle("Erase Number");
windows.setSize(550,500);
// cp.setLayout(new GridLayout(4,4));
// cp.setLayout(new FlowLayout());
//如果要自己設定button大小,將layout設定Null
//因為設定layout就是讓layout管理該container
cp.setLayout(new BorderLayout(10,10));
cp.setBackground(Color.pink);

Font font=new Font("新細明體",Font.ITALIC+Font.BOLD,50);


//game.setSize(new Dimension(200,100));
//據說會被parent的setSize重設大小,按鈕在flowlayout看起來是wrap_content
//JButton會依照文字大小變化大小
game.setPreferredSize(new Dimension(50,50));
//無視版面配置自訂元件大小?? 在BorderLayout也沒用阿
//雖然大小解決了但是字體卻變成小黑點
//利用Font物件可以指定字體大小了
//但是flowlayout還是小黑點,結果好像是JButton大小裝不下這麼大的字體


game.setFont(font);

label.setSize(200, 100);
label.setFont(font);

cp.add(label,BorderLayout.NORTH);
//BorderLayout.North不寫的話預設放在中間且填滿整個螢幕
cp.add(game,BorderLayout.CENTER);

windows.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
windows.setVisible(true);

}

2013年5月3日 星期五

Date物件,DateFormat,NumberFormat,RegularExpression

Date相關類別放在
java.util.*;


Date date = new Date();//不給參數是抓程式執行時的時間
sysout(date);
印出Fri May 03 16:27:32 CST 2013

Date date = new Date(long number);
//抓取從19701/1/8:00開始經過number豪秒的日期時間
//如果number等於九億,那麼date就是1998/7/10凌晨十二點


date.getTime();
//回傳自1970/1/1 08:00:00以來的毫秒數



NumberFormat
數字轉換格式
例如:義大利的小數點跟千分位符號跟美國相反
這兩種不同文化數字轉換可以利用NumberFormat


DateFormat
轉換日期格式
美國日期格式轉換成台灣日期格式可以利用這方式




Regular Expression規則運算式
在java以字串表示     "\\s*,\\s*"

運算式撰寫規則先指定希望使用者可以輸入的字元
\s:表示字串可以出現任何空白字元\t\n\f\r
\d:表示字串要出現0~9的數字
再從後面加上指定字元可以出現幾次
{n}:剛好出現n次
*  :指定字元出現0次以上

例子
\\d{4} :零到九的數字要出現四次



import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class DateTest {

    public static void main(String[] args) {

    Date date = new Date();
//Date(0)的話取到1970/1/1的日期
//表示經過零秒的意思

    Locale locale = Locale.getDefault();
    //取得JVM當前語言環境資訊並回傳 回傳locale物件

    //System.out.println(date);

    System.out.println(date.getTime());
//取得date記載的時間離1970/1/1經過多少毫秒
    System.out.println(Locale.getDefault());
//取得JVM使用的語言與地區  印出zh_TW

//    System.out.println(locale.getCountry());
//印出TW
//    System.out.println(locale.getDisplayCountry());
//印出台灣
//    System.out.println(locale.getLanguage());
//    System.out.println(locale.getDisplayLanguage());

    
//    NumberFormat nf=NumberFormat.getInstance(locale);
//    nf.setMaximumFractionDigits(6);
//    nf.setMinimumFractionDigits(3);
//    System.out.println(nf.format(Math.PI));
//    System.out.println(nf.format(20));
//        try {
//            Number n = nf.parse("123,456.119");
//            System.out.println(n.doubleValue());
//        } catch (ParseException ex) {
//            Logger.getLogger(DateTest.class.getName()).log(Level.SEVERE, null, ex);
//        }

    
    String ds1= "Sep 30, 2008";
    //得到一筆日期資料 美國格式
    //2008前面要空格,格式要對否則會ParseException
    DateFormat medium=DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US);
    //宣告DateFormat物件  美國日期格式 長度中型寫法Sep 30, 2008    
    try {
            date = medium.parse(ds1);
        } catch (ParseException ex) {
            Logger.getLogger(DateTest.class.getName()).log(Level.SEVERE, null, ex);
        }
    System.out.println(date);
    //印出Tue Sep 30 00:00:00 CST 2008
    
String ds2=    medium.format(date);
//將指定日期格式化回傳字串
//格式化的格式依照DateFormat當初宣告的style
    System.out.println(ds2);
    //印出Sep 30, 2008

//    如果要印台灣style的日期格式
    //另外宣告DateFormat物件
    DateFormat df=DateFormat.getDateInstance();
String ds3=  df.format(date);//date物件格式化回傳字串
    System.out.println(ds3);
    
    }
    }



import java.io.Console;

public class StringRegex {
    public static void main(String[] args) {
  //  String regex ="\\d{4}\\-\\d{1,2}\\-\\d{1,2}";
  //  \d表示0~9的數字
//        String regex ="\\d{4}-abc\\d{1,2}-\\d{1,2}";
      //減號目前測試不加上\\也沒關係
  //意思是減號跟abc一定要出現  
  String regex="";
        
        
        Console c = System.console();
    System.out.println("please input yr burthday(1222-10-11):");
   String birthday="";
    try{
     birthday=c.readLine();
    //使用者從cmd或console軟體輸入文字
   }catch(NullPointerException e){
   
   }
    boolean isValid=birthday.matches(regex);
    //比對文字是否符合regx字串規則運算式的要求
    
    System.out.println("coreect?"+isValid);
    
    
    String book="Java 城市設計,580.0,     呵呵";
    String[] bookInfo= book.split("\\s*,");
    //book字串符合split括號中規則運算式的部分會被當作分隔符號移除
    //  \\s表示任何空白字元(\t\n\f\r之類的就是)  , *表示可以出現零次以上
    //將逗號以及包含逗號前面的空白字元當作分隔符號刪掉並存入字串陣列
    System.out.println("Infomation:");
    for(String s:bookInfo)
        System.out.println(s);
    //呵呵前面的空白字元會印出來
    
    }
}

2013年5月1日 星期三

漢字相似字查詢實作

漢字一共1151個部首組成64031個漢字


編輯距離演算法應用於
兩個字串互相轉換會花掉多少成本


64031的漢字拆解成部首
利用字體部首計算字體之間相似度
如果兩個字之間共同部首越多表示這兩個字體越相似


字串之間比較:
技術上的問題,因為char只有1bytes空間
而中文字佔2bytes
用char比較每個部首之間的相似度很容易出錯
不如將兩格char存進int裡面
這樣一個int代表一個中文字

因此兩個字串之間比較事實上是兩組的數字串互相比較彼此有沒有同樣的數字
例如:比較兩組數字串的相似度
A:300 222 318 349
B:118 222 318 349


棘棗


改正:大陣列改用讀取檔案方式
傳遞陣列如果陣列太大要用傳參照方式
將插入排序改成quick sort

以上方式通通對效能增加有限
效能不好主要是因為巢狀迴圈
七萬*七萬筆資料要處理
而且每一筆都要比較到
所以要跑四十九億次才可跑完

解決方法避免不必要的字串比較
只要找出一千的編輯成本小於20的字就停止搜尋