My Calendar

2014年3月4日 星期二

UVa Problem 101 The Blocks Problems

Background 

Many areas of Computer Science use simple, abstract domains for both analytical and empirical studies. For example, an early AI study of planning and robotics (STRIPS) used a block world in which a robot arm performed tasks involving the manipulation of blocks.
In this problem you will model a simple block world under certain rules and constraints. Rather than determine how to achieve a specified state, you will ``program'' a robotic arm to respond to a limited set of commands.

The Problem 

The problem is to parse a series of commands that instruct a robot arm in how to manipulate blocks that lie on a flat table. Initially there are n blocks on the table (numbered from 0 to n-1) with block bi adjacent to block bi+1 for all 0 ≤ i < n − 1 as shown in the diagram below:


 Initial Blocks World

The valid commands for the robot arm that manipulates blocks are:
  • move a onto where a and b are block numbers, puts block a onto block b after returning any blocks that are stacked on top of blocks a and bto their initial positions.
  • move a over where a and b are block numbers, puts block a onto the top of the stack containing block b, after returning any blocks that are stacked on top of block a to their initial positions.
  • pile a onto where a and b are block numbers, moves the pile of blocks consisting of block a, and any blocks that are stacked above block a, onto block b. All blocks on top of block b are moved to their initial positions prior to the pile taking place. The blocks stacked above block a retain their order when moved.
  • pile a over where a and b are block numbers, puts the pile of blocks consisting of block a, and any blocks that are stacked above block a, onto the top of the stack containing block b. The blocks stacked above block a retain their original order when moved.
  • quitterminates manipulations in the block world.
Any command in which a = b or in which a and b are in the same stack of blocks is an illegal command. All illegal commands should be ignored and should have no affect on the configuration of blocks.

The Input 

The input begins with an integer n on a line by itself representing the number of blocks in the block world. You may assume that 0 < n< 25.The number of blocks is followed by a sequence of block commands, one command per line. Your program should process all commands until the quit command is encountered.You may assume that all commands will be of the form specified above. There will be no syntactically incorrect commands.

The Output 

The output should consist of the final state of the blocks world. Each original block position numbered i ( 0 ≤ i < n where n is the number of blocks) should appear followed immediately by a colon. If there is at least a block on it, the colon must be followed by one space, followed by a list of blocks that appear stacked in that position with each block number separated from other block numbers by a space. Don't put any trailing spaces on a line.There should be one line of output for each block position (i.e., n lines of output where n is the integer on the first line of input).

Sample Input 

10
move 9 onto 1
move 8 over 1
move 7 over 1
move 6 over 1
pile 8 over 6
pile 8 over 5
move 2 over 1
move 4 over 9
quit

Sample Output 

 0: 0
 1: 1 9 2 4
 2:
 3: 3
 4:
 5: 5 8 7 6
 6:
 7:
 8:
 9:


解題方法:這題最重要的是要明白題意,不會太難。從題目的要求發現可以採用Stack進行實作。


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;


public class UvA101 {
      public static Stack blocks[];
      public static int[] position;
      public static int numberOfblocks;
      public static String command ="";
      public static int a,b;
    
    public static void main(String[] args) throws IOException{
      // Defined Variable
    
      BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
      numberOfblocks = Integer.parseInt(buf.readLine());
      blocks = new Stack[numberOfblocks];
      position = new int[numberOfblocks];
      
      for(int i = 0; i < numberOfblocks; i++) {
          blocks[i] = new Stack(); // Initial number of empty stack
          blocks[i].push(i);
          position[i] = i;
      }
      
      while(!(command=buf.readLine()).equals("quit")){
       
       StringTokenizer token = new StringTokenizer(command);
       String aWord = token.nextToken();
          a = Integer.parseInt(token.nextToken());
          String bWord = token.nextToken();
           b = Integer.parseInt(token.nextToken());
       
          if(a==b || position[a]==position[b])
           continue;
      
          if(aWord.equals("move"))
          {
           if(bWord.equals("onto"))
           {
            moveOnto(a,b);
           }
           else if(bWord.equals("over"))
           {
            moveOver(a,b);
           }
          }
          else if(aWord.equals("pile"))
          {
           if(bWord.equals("onto"))
           {
            pileOnto(a,b);
           }
           else if(bWord.equals("over"))
           {
            pileOver(a,b);
           }
          }
          
      }
      
      for(int i = 0; i < blocks.length; i++) 
       System.out.println(answer(i));
    }
     public static void moveOnto(int a, int b) {
        clearAbove(b);
        moveOver(a, b);
     }
     
     public static void moveOver(int a, int b) {
      clearAbove(a);
         blocks[position[b]].push(blocks[position[a]].pop());
         position[a] = position[b];
      }
     
     public static void  pileOnto(int a, int b) {
      clearAbove(b);
         pileOver(a, b);
      }
     
     public static void pileOver(int a, int b) {
      Stack pile = new Stack();
         while(blocks[position[a]].peek() != a) {
             pile.push(blocks[position[a]].pop());
         }
         
         pile.push(blocks[position[a]].pop());
         while(!pile.isEmpty()) {
            int Tmp = pile.pop();
            blocks[position[b]].push(Tmp);
            position[Tmp] = position[b];
         }
      }
     
     public static void clearAbove(int block) {
      while(blocks[position[block]].peek() != block) {
             initial(blocks[position[block]].pop());
          }
      }
     
     /* 
      * Initial the blocks
      */
     
     public static void initial(int block) {   
         while(!blocks[block].isEmpty()) {
            initial(blocks[block].pop());
         }
         blocks[block].push(block);
         position[block] = block;
     }
     
     public static String answer(int index) {
         String Result = "";
         while(!blocks[index].isEmpty()) Result = " " + blocks[index].pop() + Result;
         Result = index + ":" + Result;
         return Result;
     }
  }

UVa Problem 12289 - One-Two-Three

UVa Problem 12289 - One-Two-Three

Time limit: 1.000 seconds

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=24&problem=3710&mosmsg=Submission+received+with+ID+19897820

Your little brother has just learned to write one, two and three, in English. He has written a lot of those words in a paper, your task is to recognize them. Note that your little brother is only a child so he may make small mistakes: for each word, there might be at most one wrong letter. The word length is always correct. It is guaranteed that each letter he wrote is in lower-case, and each word he wrote has a unique interpretation.

Input 
The first line contains the number of words that your little brother has written. Each of the following lines contains a single word with all letters in lowercase. The words satisfy the constraints above: at most one letter might be wrong, but the word length is always correct. There will be at most 10 words in the input.

Output 
For each test case, print the numerical value of the word.

Sample Input 
3
owe
too
theee

Sample Output 
1
2
3

解題方法 : Input 敘述中提到每個word的長度一定是對的 那首先只要判斷字的長度是 5 肯定就是3. one 和 two 擇一判斷輸入的每個字元是否有兩個或以上的字元相等.


import java.util.Scanner;

class Uva12289 {
 public static void main(String args[]) {
  
  Scanner scan = new Scanner(System.in); 
  int n= scan.nextInt();
  for(int i = 0 ; i < n ;i++) {
   String inputWords = scan.next();
   if(inputWords.length() == 5 )
    System.out.println("3");
   else{
    int cnt = 0 ;
    if( inputWords.charAt(0)=='o')
     cnt++;
    if( inputWords.charAt(1)=='n')
     cnt++;
    if( inputWords.charAt(2)=='e')
     cnt++;
    
    if(cnt >=2 )
     System.out.println("1");
    else
     System.out.println("2");
   }      
  }   
 }

}

2014年3月3日 星期一

UVa Problem 100 The 3n+1 problem

The 3n + 1 problem

Time limit: 3.000 seconds

Background

Problems in Computer Science are often classified as belonging to a certain class of problems (e.g., NP, Unsolvable, Recursive). In this problem, you will be analyzing a property of an algorithm whose classification is not known for all possible inputs.

The Problem

Consider the following algorithm:

       1.   input n

       2.   print n

       3.    if n = 1 then STOP

       4.       if n is odd then n ←− 3n + 1

       5.       else  n ←− n/2

       6.     GOTO 2
Given the input 22, the following sequence of numbers will be printed 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1

It is conjectured that the algorithm above will terminate (when a 1 is printed) for any integral input value. Despite the simplicity of the algorithm, it is unknown whether this conjecture is true. It has been verified, however, for all integers n such that 0 < n < 1,000,000 (and, in fact, for many more numbers than this.)



Given an input n, it is possible to determine the number of numbers printed (including the 1). For a given n this is called the cycle-length of n. In the example above, the cycle length of 22 is 16.



For any two numbers i and j you are to determine the maximum cycle length over all numbers between i and j.


The Input

The input will consist of a series of pairs of integers i and j, one pair of integers per line. All integers
will be less than 10,000 and greater than 0.
You should process all pairs of integers and for each pair determine the maximum cycle length over
all integers between and including i and j.

You can assume that no operation overflows a 32-bit integer

The Output

For each pair of input integers i and j you should output i, j, and the maximum cycle length for
integers between and including i and j. These three numbers should be separated by at least one space
with all three numbers on one line and with one line of output for each line of input. The integers i
and j must appear in the output in the same order in which they appeared in the input and should be
followed by the maximum cycle length (on the same line).


Sample Input

1 10
100 200
201 210
900 1000
Sample Output

1 10 20
100 200 125
201 210 89
900 1000 174

解題方法:這題相當容易,只要根據題目所給的演算法就可以。但請注意系統給的測資 i 和 j 不一定是由小到大也有可能由大到小,所以要使用Math.min()的功能確定 i 和 j 那個比較小當for loop的初始值。

 import java.util.Scanner;
public class Problem100 
{
 public static void main(String[] args) 
 {
 
     Scanner scan = new Scanner(System.in);
     int from,to,max=0,temp;
   
  while(scan.hasNextInt())
  {
       from=scan.nextInt();
       to=scan.nextInt();
           
       for(int n=Math.min(from, to);n<=Math.max(from, to);n++)
       {
        temp=cycle_length(n);
        if(temp>max)
        {
         max=temp;
        }
       }  
       System.out.println(from + " " + to + " " + max); 
       max=0;
  }       
 } 
 // function cycle_length
 public static int cycle_length(int n)
 {
  int length=1;
  while(n!=1)
  {
   if((n%2)==1)
    n=3*n+1;  
   else
    n=n/2;
   length++;
  }
   return length;
 } // end function cycle_length

}// end class Main

2012年9月16日 星期日

HTTP

HTTP

            HTTP是Hyper Text Transfer Protocol的縮寫,這是一種通訊協定,架構與TCP/IP之上應用層的一種協定。通訊協定基本上就是兩台電腦間溝通的方式。依不同的連線方式與所使用的網路服務而定,會有不同的通訊協定。例如發送信件時用SMTP,傳輸檔案用FTP等等。而瀏覽器跟Web伺服器之間的溝通方式,則是HTTP,它有兩個非常重要的特性:
  • 請求(Request)/ 回應(Response)模型
  • 無狀態(Stateless)通訊協定
             HTTP是基於請求/回應的通訊協定,客戶端對伺服器放出一個取得一個資源的請求,伺服器將要求的資源回應給客服端,每次的連線只作一次請求/回應,沒有請求就不會有回應。


             在HTTP協定下,伺服器是一個健忘的傢伙。伺服器回應客服端後,就不會記得客戶端的資訊,更不會維護與客戶端之間的狀態。因此HTTP又稱為Stateless 通訊協定。

HTTP 請求方法
瀏覽器在使用HTTP發出請求時,有幾種請求方法:
  • GET     請求獲取Request-URI所標識的資源
  • POST    在Request-URI所標識的資源後附加新的數據
  • HEAD    請求獲取由Request-URI所標識的資源的響應消息報頭
  • PUT    請求服務器存儲一個資源,並用Request-URI作為其標識
  • DELETE  請求服務器刪除Request-URI所標識的資源
  • TRACE   請求服務器回送收到的請求信息,主要用於測試或診斷
  • CONNECT 保留將來使用
  • OPTIONS 請求查詢服務器的性能,或者查詢與資源相關的選項和需求

在日常生活中最常接觸的請求方法就是GET和POST這兩種方法。以下分別介紹GET和POST的使用。

GET
GET 顧名思義,就是向伺服器取得指定的資源,在發出GET請求時,必須告訴伺服器所請求資源的URL,例如一個GET請求的發送範例如下:

在上圖中,請求標頭的內容是傳給伺服器參考的額外資訊。請求參數通常是使用者發送給伺服器的必要資訊 。請求資訊通常是使用者傳給伺服器的必要資訊,這些資訊通常是透過表單進行發送,伺服器必須有這些資訊才可以進一步對使用者的請求作出正確的回應,請求參數是在URL之後跟隨一個問號(?) 然後就是請求參數名稱和請求參數值,如果需要多個請求參數,則以&字元連接。GET請求可以發送的請求參數長度是有限的,對於太大量的資料不適合用GET進行傳送,這時候可以改成POST

POST請求
POST請求就是讓你請求時發怖(POST)資訊給伺服器,對於大量或是複雜的資訊,基本上都會採用POST來進行發送,一個POST發送的例子如下:





            從上圖中可以看到,POST的請求參數從URL轉移到訊息本體當中。因為訊息本體的內容長度沒有限制,所以大量的資料發送都會使用POST方法。而且請求參數移到訊息本體中,因此一些敏感資訊即使長度不長,通常也會採用POST方法發送。




  

2012年7月30日 星期一

URN,URL,URI是什麽

URN、URL和URI是什麽?

介紹URL,URN,URI這三個名詞之前,首先它們的全名分別為:
  • URL  :Uniform Resource Locator
  • URN :Uniform Resource Name
  • URI   :Uniform Resource Identifier

URL
URL的主要目的是透過文字的方式說明網際網路上的資源如何取得。URL的主要格式為:

<協議>:<特定協議部分>

協議指定了以何種方式取得資源,一些比較著名的協議名字有:
  • ftp (檔案傳輸協定)
  • http (超文本傳輸協定)  
  • mailto (電子郵件)
  • file (檔案名稱)
特定協議部分的格式為:

//<使用者>:<密碼>@<主機>:<埠號>/<路徑>

簡單來說URL就是代表資源的位址資訊。

URN
URN是代表某個資源獨一無二的名稱,舉例來說,每一本書都會有一個獨一無二的ISBN碼,現在有一本書的名字是“aaa” ,它的ISBN為『ISBN 111-222-333-444-5』這個ISBN就是URN。

URI
URN 和 URL的目的都是迎來識別某個資源,後來的標準制定了URI,而URN與URL成為URI的子集。如果相對URL、URI與URN的歷史演進與標準發怖更多的了解可參考一下的網址。


參考資料:
  1. Servlet/JSP 教學手冊
  2. www.wikipedia.org


2012年5月5日 星期六

String,StringBuilder和StringBuffer的區別

      在日常開發中串接字串是常有的工作,Java有三種方式處理字串串接分別是String, StringBuilderStringBuffer(JDK1.5 才提供) 這三種都可以達到我們想要的效果,但各自在使用上還是有些區別。

具體看以下的例子講解:
String str = "" ;
for(int i=0 ; i<10000 ; i++)
    str+="java";

相信大家都知道String這個類別是屬於Immutable Object,不知道的可以到Java String和String Pool查看。以這段code來說用迴圈進行大量的串接字串的工作,在效能上會有隱憂。所以Java提供了其他的方法提高效能。

我們為這三個方式做一個小測試。

public class Test {
 public static void main(String args[])
 {
  testString();
  testStringBuffer();
  testStringBuilder();
 }
 
 public static void testString()
 {
  String str = "" ;
  long begin = System.currentTimeMillis();  
  for(int i=0 ; i<10000 ; i++)
   str+="java";
                long end = System.currentTimeMillis();       
                System.out.println("String Spend Time:"+(end-begin)+"ms");
 }
 
 public static void testStringBuffer()
 {
  StringBuffer sbuf = new StringBuffer();
  long begin = System.currentTimeMillis();
  for(int i=0 ; i<10000 ; i++)
   sbuf.append(i);
  long end = System.currentTimeMillis();       
  System.out.println("String Buffer Time:"+(end-begin)+"ms");
 }
 
 public static void testStringBuilder()
 {
  StringBuilder sb = new StringBuilder();
  long begin = System.currentTimeMillis();
  for(int i=0 ; i<10000 ; i++)
      sb.append("java");
         long end = System.currentTimeMillis();  
         System.out.println("String Builder Spend Time:"+(end-begin)+"ms");
 }
 
}

執行結果:






從上面的結果可以看到同樣的工作StringBuilderStringBuffer的處理時間是差不多,但String的處理時間相對於其他兩種方式慢了很多。

在一般情況執行效率StringBuilder>StringBuffer>String,不一定所有情況都是這樣。

String: 適合在少量的字符串操作的情況。
StringBuilder:適合在單線程下進行大量操作的情況
StringBuffer:適合在多線程進行大量操作的情況

在compile的時候可以確定字串的常量,那沒必要使用StringBuilderStringBuffer,直接使用String常量"+"進行連接效率最好。



2012年5月2日 星期三

Java String和String Pool

     在開發Java應用程式當中String是我們常用的一個物件,要理解String的運作方式,首先要知道String是一個Immutable Object

宣告
宣告String有兩種方式 :
String str1 = "abc";
String str2 = new String("abc");
雖然這兩種方式都可以宣告String的物件,但JVM對於這兩種的處理方式是不一樣的。第一種首先會在String Pool中尋找是否存在,如果有就從String Pool回傳該String物件,反之將該常量新增到String Pool中。第二種則會在Heap Memory新增一個物件,而不是String Pool中。

String Pool
String Pool是Java Heap Memory中儲存String的一個區域。當使用常量(literal)方式宣告String物件JVM會從String Pool檢查是否有相同的字串,如果有將會從String Pool回傳該實例,而不會重分配新的記憶體,從而達到節省記憶體的目的。

例子:
String str1 = "abc";
String str2 = "abc";


















使用new關鍵字宣告的方式就會在Heap Memory新增一個字串,而不管該字串是否在String Pool中。
String str3 = new String("abc");
String str4 = new String("abc");

















我們看以下的code就能更加清楚。
public class Test {
 public static void main(String args[])
 {
  String str1 = "abc";
  String str2 = "abc";
  String str3 = new String("abc");
  String str4 = new String("abc");
  
  System.out.println(str1==str2);
  System.out.println(str1==str3);
  System.out.println(str3==str4);
  System.out.println(str1==str3.intern()); 
 }
}

執行的結果是
true
false
false
true

==只能判定兩個instance是否指向同一個記憶體位址(M.A),而不是M.A裡面的內容。從結果可以看出 str1==str2 是true原因是雙方都是指向在String pool裡面同一個M.A,反之str1==str3會是false

雖然str3的內容和str1一樣,但因為宣告方式的不同造成str3不會在String pool裡面尋找,而是直接在Heap memory重新分配新的M.A給str3。str3==str4是false也是M.A的不同。在String有一個方法可以先從String Pool裡面尋找該內容那就是intern()。str1==str3.intern()是true是可以預料的,str3調用intern()方法造成str3指向的M.A會和str1一樣。