Haskell:打印案例编号 [英] Haskell: Print case number

查看:82
本文介绍了Haskell:打印案例编号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个Haskell代码:

I have written a Haskell code as:

loop = do
 x <- getLine
 if x == "0"
  then return ()
  else do arr <- replicateM (read x :: Int) getLine 
          let blocks = map (read :: String -> Int) $ words $ unwords arr
          putStr "Case X : output = "; -- <- What should X be?
          print $ solve $ blockPair blocks;
          loop

main = loop

这终止于0输入。我也想打印案例编号,例如。 案例1,2 ...

This terminates at 0 input. I also want to print the case number eg. Case 1, 2 ...

运行示例:

Sample run:

1
10 20 30
Case 1: Output = ...
1
6 8 10
Case 2: Output = ...
0 

有人知道如何做到这一点吗?另外,如果可能的话,你可以建议我在最后打印输出行吗?

Does anyone know how this can be done? Also, If possible can you suggest me a way to print the output line at the very end?

预先感谢。

Thanks in advance.

推荐答案

对于问题的第一部分,当前案例编号是您在程序执行过程中想要维护的某个状态的示例。在其他语言中,您肯定会使用可变变量。

For the first part of your question, the current case number is an example of some "state" that you want to maintain during the course of your program's execution. In other languages, you'd use a mutable variable, no doubt.

在Haskell中,有几种处理状态的方法。最简单的一个(尽管它有时候有点难看)是将状态明确地作为函数参数传递,并且考虑到已经构建好代码的方式,这将非常有效。

In Haskell, there are several ways to deal with state. One of the simplest (though it is sometimes a little ugly) is to pass the state explicitly as a function parameter, and this will work pretty well given the way you've already structured your code:

main = loop 1

loop n = do
  ...
  putStr ("Case " ++ show n ++ ": Output = ...")
  ...
  loop (n+1)  -- update "state" for next loop

您的问题的第二部分涉及更多一点。它看起来像你想提示而不是解决方案。为了让你开始,让我告诉你一个函数的例子,该函数读取行,直到用户输入 end ,然后返回所有行的列表,直到但不包括 end (与 main 函数一起使用,这些函数对使用大多数纯代码的行感兴趣):

The second part of your question is a little more involved. It looks like you wanted a hint instead of a solution. To get you started, let me show you an example of a function that reads lines until the user enters end and then returns the list of all the lines up to but not including end (together with a main function that does something interesting with the lines using mostly pure code):

readToEnd :: IO [String]
readToEnd = do
    line <- getLine
    if line == "end"
      then return []
    else do
      rest <- readToEnd
      return (line:rest)

main = do
    lines <- readToEnd
    -- now "pure" code makes complex manipulations easy:
    putStr $ unlines $
      zipWith (\n line -> "Case " ++ show n ++ ": " ++ line)
              [1..] lines

编辑:我想你想要一个更直接的答案,而不是一个提示,所以你将采用上述方法来阅读块列表的方法是写一些东西e:

I guess you wanted a more direct answer instead of a hint, so the way you would adapt the above approach to reading a list of blocks would be to write something like:

readBlocks :: IO [[Int]]
readBlocks = do
  n <- read <$> getLine
  if n == 0 then return [] else do
    arr <- replicateM n getLine
    let block = map read $ words $ unwords arr
    blocks <- readBlocks
    return (block:blocks)

然后 main 看起来像这样:

and then main would look like this:

main = do
  blocks <- readBlocks
  putStr $ unlines $
    zipWith (\n line -> "Case " ++ show n ++ ": " ++ line)
          [1..] (map (show . solve . blockPair) blocks)

这篇关于Haskell:打印案例编号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆