如何在Common Lisp中实现这个问题?

时间:2011-01-30 13:48:37

标签: common-lisp

我是一名初学程序员,对Common Lisp非常感兴趣,但根本不了解它。我非常感谢能在Common Lisp中实现以下问题的人,所以我可以看到Common Lisp如何处理基本的东西,比如字符串处理,文件I / O等。

问题在于:

输入示例,从“problem.in”文件中读取

3 5 
XHXSS 
XSHSX 
XXHSS

您通过 w 字符表获得 h 。第一个数字是行数,第二个数字是列数。

对于每列字符,您应该执行以下操作:

从头到尾开始查看字符。

如果找到'X',则输出列的成本(默认情况下成本为零),后跟空格字符,然后转到下一列(跳过当前列中的所有其他字符)。

如果找到“S”,则将费用增加1。

如果找到“H”,则将成本增加3。

如果列中没有'X',则输出'N'后跟空格字符。

输出示例,写入“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)
(...))

...
)

2 个答案:

答案 0 :(得分: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 "

答案 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)))))