2011-01-30 58 views
2

我是一位初级程序员,对Common Lisp非常感兴趣,但根本不知道它。我会非常感谢任何能够在Common Lisp中实现以下问题的人,所以我可以看到Common Lisp如何处理基本的事情,如字符串处理,文件I/O等。如何在Common Lisp中实现这个问题?

这里是问题:

输入的

实施例,从 “problem.in” 文件读

3 5 
XHXSS 
XSHSX 
XXHSS 

您给出ħ通过瓦特表字符。第一个数字是行数,第二个数字是列数。

对于字符的每一列,你应该做到以下几点:

开始通过字符寻找从上到下。

如果找到'X',输出列的开销(默认为cost为0),后跟空格字符,然后转到下一列(跳过当前列中的所有其他字符)。

如果找到“S”,由1

如果发现“H”增加了成本,由3

增加成本如果有在列,输出“N无“X” '接着是空间角色。输出

例,写入 “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; 
} 

我宁愿看到这个问题实现为一个功能,沿着这些线:

(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 2011-01-30 20:55:25

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 2011-01-30 15:17:08