Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell将点列表转换为字符串_Haskell_Functional Programming - Fatal编程技术网

Haskell将点列表转换为字符串

Haskell将点列表转换为字符串,haskell,functional-programming,Haskell,Functional Programming,我正在做作业,我需要一些帮助。这是最后一部分,但我真的很挣扎,不知道如何处理。问题是: 添加一个函数render,该函数获取图像并返回一个字符串, 如果打印,将给出图像的图示,如下所示 如下图所示(确保包括周围的一点边界 图像的所有侧面)。例如,render t应该返回 ".|...\n.xxx.\n-+x--\n.|...\n" (图像中的点表示为“x”,原点表示为 “+”,水平轴和垂直轴表示为“-”和“|” 分别): (我们通过render t函数生成的字符串可以通过putStr打印出来

我正在做作业,我需要一些帮助。这是最后一部分,但我真的很挣扎,不知道如何处理。问题是:

添加一个函数render,该函数获取图像并返回一个字符串, 如果打印,将给出图像的图示,如下所示 如下图所示(确保包括周围的一点边界 图像的所有侧面)。例如,render t应该返回

".|...\n.xxx.\n-+x--\n.|...\n"
(图像中的点表示为“x”,原点表示为 “+”,水平轴和垂直轴表示为“-”和“|” 分别):

(我们通过render t函数生成的字符串可以通过putStr打印出来 (渲染t)以实现上述结果)

图像和t就是这样:

type Point = (Int,Int)
type Image = [Point]
t :: Image
t=[(0,1),(1,0),(1,1),(2,1)]

首先,我需要另一个函数,因为它不能全部在渲染中完成。我知道要看y和x的最大/最小值来得到边界,我有一个函数。我还有一个函数,它将在每n个字符后向字符串中插入换行符。

因此您有一个函数来获取尺寸:

dimensions :: Image -> (Point, Point)
返回左上角和右下角。然后,我将按顺序获得分数:

sortImage :: Image -> Image
它首先按最大的
y
和最小的
x
进行排序(提示:
Data.List.sortBy
是您的朋友)。这实际上不是必要的,但它可以让以后的事情变得更容易。然后您可以创建一个空白图像(即仅轴和
,或者您可以使用空格以获得更清晰的外观)

超出你的范围。一定要返回一个行列表,以后可以使用新行连接,但现在要使其更易于使用。现在,
[String]=[[Char]]
,这样就有了一个2D字符数组。您有一个指示坐标的
点列表,但您必须移动它们,以便您的左上角坐标现在是
(0,0)
。这样我们就可以在数组上使用普通索引来设置点。幸运的是,我们已经计算了
维度中的偏移值

然后您需要一个函数,该函数获取
blankImage
的输出,并使用现在偏移量
图像中的值替换字符。由于
现在是
空白图像
中的索引,这应该很容易

fillImage :: Image -> [String] -> [String]
因此,过程是:

import Data.List

showImage :: Image -> String
showImage img = intercalate "\n" filled
    where
        sortedImg = sorteImage img
        (upperL, lowerR) = dimensions sortedImg
        blank = blankImage (upperL, lowerR)
        offsetImg = offsetImage upperL sortedImg
        filled = fillImage offsetImg blank
    putStrLn $ intercalate "\n" filled
函数
插入
将在
[String]
中加入新行,将其变成一个大字符串



我从你的评论中看到,你是哈斯克尔的新手,所以我想说,如果你需要更多的帮助,我会给你更多的提示,但你最好先自己解决这个问题。如果您遇到困难,请发表评论,我将编辑我的答案以帮助您克服障碍。

以下是一些需要思考的问题:

  • 从功能上讲,什么是图像?现在忽略边界,图像是从坐标到该坐标上显示的任何对象的函数。尝试为图像创建一个类型签名。如果您使用
    类型
    将其称为
    FImage
    ,则可获得额外积分。将这些函数视为主要对象(记住,函数是一等公民)
  • 执行轴,如图所示。请注意,您不需要任何边界。那不是很棒吗
  • 执行一个函数,获取一个
    FImage
    和一个
    ,并生成一个
    FImage
    ,其
    x
    位置正确
  • 从点列表中找出边界。像往常一样,总是先想一想:这是什么类型的签名
  • 给定一个
    FImage
    和边界,生成最终的
    字符串。您可能需要在此处使用列表理解
  • 把它们放在一起。这里隐藏着一个褶皱!它的一个论点是点列表。其他参数是什么(基本情况和组合函数)。在Haskell的这一专业水平上,不用太担心它是
    foldl
    还是
    foldr
    ,两者都可以工作(如果类型匹配)
  • 完成:-)
学习愉快


(这以前是这个问题的一个重要部分。)

Haskel可以让你头脑清醒一点,特别是当你刚刚开始的时候。只是为了澄清一下,您需要一个函数来将
t=[(0,1),(1,0),(1,1),(2,1)]
转换为
。|…\n.xxx。\n-+x--\n.|…\n“
对于图像的大小是否有任何定义的限制,或者我们的函数是否需要自行确定?我的意思是更像点的位置。如果其中一点是
(11000)
我们的形象将变得非常大。这是我所知道的haskell最好的资源,我现在正在工作,但我会尽力帮助你找到合适的答案,当我有机会的时候。即使回想起来你对这个问题不满意,编辑掉这个问题也无济于事。请放回原处。您可能应该使用
unlines
而不是
interlate“\n”
,因为示例的末尾(在最后一行之后)也有一个换行符。这取决于用例。我个人更喜欢
interlate
,因为它的行为类似于Python中的
string.join
,Python是我的主要语言。如果有人想更改为
“\r\n”
,这很容易解决。但实际上,它们本质上是等价的方法,差别很小。
fillImage :: Image -> [String] -> [String]
import Data.List

showImage :: Image -> String
showImage img = intercalate "\n" filled
    where
        sortedImg = sorteImage img
        (upperL, lowerR) = dimensions sortedImg
        blank = blankImage (upperL, lowerR)
        offsetImg = offsetImage upperL sortedImg
        filled = fillImage offsetImg blank
    putStrLn $ intercalate "\n" filled