2011-01-30 5 views
2

私は初心者ですが、Common Lispに非常に興味がありますが、それはまったく分かりません。私はCommon Lispで以下の問題を実装することができる誰にも非常に感謝しています。Common Lispが文字列処理、ファイルI/Oなどの基本的な処理をどのように処理するかを見ることができます。Common Lispでこの問題を実装する方法は?

ここに問題があります:

あなたは、文字のテーブルwを によって時間を与えられている

3 5 
XHXSS 
XSHSX 
XXHSS 

入力の例は、 "problem.in" ファイルから読み取ります。最初の数値は行数、2番目の数値は列数です。あなたが次のことを行う必要があり、文字の列ごと

上から下へ文字を見始めます。

'X'が見つかった場合は、コストを出力します(コストはデフォルトで0です)。次に空白文字を入力し、次の列に移動します(現在の列の他の文字はすべてスキップします)。

「S」が見つかった場合は「H」が見つかった場合は、「X」の列において、出力「Nが存在しなかった場合3.

によってコストを増大させる、1

によってコストを増大させますスペース文字が続きます。 "problem.out" ファイルに書き込まれる出力の

例、:ここで

0 4 0 N 1 

は、C++での私の実装です:

#include <iostream> 
#include <fstream> 
#include <string> 

using namespace std; 

int main(void) 
{ 

    ifstream input; 
    input.open("problem.in"); 

    ofstream output("problem.out"); 

    int h, w; 
    input >> h >> w; 

    string * str = new string[h]; 

    for(int i = 0; i < h; i++) input >> str[i]; 

    for(int i = 0; i < w; i++) 
    { 

     int cost = 0; 
     bool found = false; 

     for(int j = 0; j < h; j++) 
     { 
      char ch = str[j][i]; 
      if(ch == 'X') { found = true; break; } 
      else if(ch == 'S') cost += 1; 
      else if(ch == 'H') cost += 3; 
     } 

     if(found) output << cost; 
     else output << 'N'; 

     output << ' '; 
    } 

    input.close(); 
    output.close(); 

    return 0; 
} 

私はこの問題は1として実装見ることを好むだろうこれらの線に沿った何か:

(defun main() 

... 

(with-open-file (input "problem.in" :direction :input) 
(...)) 

... 

(with-open-file (output "problem.out" :direction :output :if-exists :supersede) 
(...)) 

... 
) 

答えて

7
(defun solve-problem (in-file out-file) 
    (labels ((solve (in out) 
      (let ((h (read in)) 
        (w (read in))) 
       (compute-output out h w 
           (read-array in h w (make-array (list h w)))))) 
      (read-array (stream h w array) 
      (loop for i below h do (read-line stream) 
        (loop for j below w 
         do (setf (aref array i j) 
            (read-char stream)))) 
      array) 
      (compute-output (stream h w array) 
      (loop with x-p and cost for j below w do 
       (setf x-p nil cost 0) 
       (loop for i below h do 
       (case (aref array i j) 
        (#\X (setf x-p t) (return)) 
        (#\S (incf cost)) 
        (#\H (incf cost 3)))) 
       (format stream "~a " (if x-p cost #\N))))) 
    (with-open-file (in in-file) 
     (with-open-file (out out-file :direction :output :if-exists :supersede) 
     (solve in out))))) 

CL-USER 17 > (solve-problem "/tmp/test.data" "/tmp/result.text") 
NIL 

CL-USER 18 > (with-open-file (stream "/tmp/result.text") (read-line stream)) 
"0 4 0 N 1 " 
+0

これを書いていただきありがとうございます。あなたのコードにいくつか問題があります。あなたは正しい結果を得ているようですが、私は次の結果を得ます(Windows 7):Clozure Common Lisp 1.6では、結果は 0 3 0 4 Nです。 Lispworks Personal 6.01の場合、結果は 処理中のエラーです。 ストリーム#を読み込み中にファイルの終わり。 – Max

+0

@Max:私のMacでClozure CLを使って正しい結果を得ました。どこでLispWorksのエラーが出ますか?解決の呼び出しで? –

+0

このバージョンをお試しください。 MacとWindowsの違いの1つは、行末です... –

2

あなたはではないこれは、単一の機能でこれを行う今日。 70年代は終わった。

関数read-problem-setを定義すると、それぞれが文字のリストである行のリストが返されます。次に、関数transposeを定義し、その列を列のリストに置き換えます。計算の「肉」は、列を読み込んでそのコストを返す関数costによって行われます。最後に、指定されたファイルに必要な形式でリストを書き込む関数output-column-costsを書くことができます。機能solve-problemにすべてのピースを接続します

(defun solve-problem (in-file out-file) 
    (output-column-costs out-file 
         (mapcar #'cost 
           (transpose (read-problem-set in-file))))) 
+0

私はそれは多くの機能で実現できることを知っているが、私は意識的に一つの機能を選択しました。私はちょうどそれがどのように見えるかを見たかった。しかし、とにかく、どんな種類の完全な作業の実装がうまくいくでしょう。 :-) – Max

関連する問題