2011-01-30 5 views
2

나는 커먼 리스프에 관심이지만, 전혀 모르는 시작 프로그래머입니다. Common Lisp에서 다음과 같은 문제를 구현할 수있는 누구에게나 매우 감사 할 것입니다. 그래서 Common Lisp에서 문자열 처리, 파일 I/O 등과 같은 기본적인 작업을 처리하는 방법을 알 수 있습니다.Common Lisp에서이 문제를 어떻게 구현합니까?

여기에 문제가 있습니다 :

"problem.in"파일에서 읽어 입력

예 : 당신은 문자의 테이블 승 에 의해 시간를 부여

3 5 
XHXSS 
XSHSX 
XXHSS 

. 첫 번째 숫자는 행 수이고 두 번째 숫자는 열 수입니다.

는 위에서 아래로 문자를 통해보고 시작 : 다음을 수행해야합니다 문자의 각 열에 대한

.

'X'가 발견되면, 열 출력 비용 (비용은 기본적으로 제로) 공백 문자 뒤에 다음 (현재 열에서 다른 모든 문자를 건너 뛰는) 다음 열로 이동합니다. 'S'가 발견되면 'H'가 발견되면 열 출력 'N에는'X '는 없었다 경우

3.

하여 비용을 증가 1.

하여 비용을 증가 '다음에 공백 문자가옵니다. "problem.out"파일에 기록 된 출력의

예 :

#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; 
} 

나는이 문제가 하나로 구현을 참조하는 것을 선호 : 여기

0 4 0 N 1 

는 C++에서 내 구현 함수, 다음 줄을 따라 뭔가 :

(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

시간을내어 작성해 주셔서 감사합니다. 귀하의 코드에 몇 가지 문제가 있습니다. 당신은 올바른 결과를 얻을 것 같다,하지만 난 (윈도우 7) 다음과 같은 결과를 얻을 : Clozure 커먼 리스프 1.6에서 결과가 0 3 0 4 N입니다. Lispworks Personal 6.01에서 결과는 다음과 같습니다. 오류가 발생했습니다. 스트림 # 을 읽는 동안 파일의 끝. – Max

+0

@Max : Mac에서 Clozure CL을 사용하여 올바른 결과를 얻었습니다. 어디서 LispWorks 오류가 발생합니까? 해결할 전화? –

+0

이 버전을 사용해보십시오. Mac과 Windows의 차이점 중 하나는 라인 엔드입니다 ... –

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

관련 문제