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_Base Conversion - Fatal编程技术网

在Haskell中将负基二进制转换为十进制:";…的实例。。“必需”;

在Haskell中将负基二进制转换为十进制:";…的实例。。“必需”;,haskell,base-conversion,Haskell,Base Conversion,我必须编写两个函数,将十进制数转换成(-2)个阿迪亚数系统(类似于二进制,只有-2),反之亦然。 我已经设法使十进制->(-2)adian运行。 但是对于(-2)adian->decimal,我有一个问题,就是不知道从哪里开始。 希望你能帮助我 type NegaBinary = String -- Function (-2)adisch --> decimal negbin_dezi :: NegaBinary -> Integer -> Integer negbin_de

我必须编写两个函数,将十进制数转换成(-2)个阿迪亚数系统(类似于二进制,只有-2),反之亦然。 我已经设法使十进制->(-2)adian运行。 但是对于(-2)adian->decimal,我有一个问题,就是不知道从哪里开始。 希望你能帮助我

type NegaBinary = String

-- Function (-2)adisch --> decimal
negbin_dezi :: NegaBinary -> Integer -> Integer
negbin_dezi (xs:x) n 
    | (x == 0) = if ([xs] == "") then 0 else (negbin_dezi [xs] (n+1))
    | (x == 1) = if ([xs] == "") then (-2)**n else (-2)**n + (negbin_dezi [xs] (n+1))
它总是抛出: 定义negbin_dezi所需的(Num[Char],浮点整数)实例

有人知道为什么它不起作用吗? 请:)

一些问题:

  • x==0
    x==1
    ,但是
    x
    是一个
    Char
    ,所以您的意思是
    x==0'

  • 您可以编写
    (xs:x)
    。列表末尾没有匹配模式。也许可以使用一个帮助函数先反转列表

  • [xs]
    只有一个元素,永远不会是
    。请使用基本大小写

  • 模式匹配比相等性检查更有用

  • **
    表示浮点幂,
    ^
    表示整数幂

  • 您经常使用
    [xs]
    来表示
    xs
    。不需要用方括号来列出

  • 下面是一个有效的重写:

    negbin_dezi1 :: NegaBinary -> Integer
    negbin_dezi1 xs = negbin (reverse xs) 0
    
    negbin []     _ = 0
    negbin (x:xs) n 
        | x == '0' = negbin xs (n+1)
        | x == '1' = (-2)^n + (negbin xs (n+1))
    
    最好使用模式匹配:

    negbin_dezi2 :: NegaBinary -> Integer
    negbin_dezi2 xs = negbin (reverse xs) 0 where
      negbin []     _ = 0
      negbin ('0':xs) n =          negbin xs (n+1)
      negbin ('1':xs) n = (-2)^n + negbin xs (n+1)
    
    但如果将“0”转换为0,将“1”转换为1,然后乘以该值,可能会更好:

    val :: Char -> Int
    val '0' = 0
    val '1' = 1
    
    negbin_dezi3 :: NegaBinary -> Integer
    negbin_dezi3 xs = negbin (reverse xs) 0 where
      negbin []     _ = 0
      negbin (x:xs) n = val x * (-2)^n  +  negbin xs (n+1)
    

    不过,我不会那样写:

    另一种完全不同的方法是立即考虑整个事情

    "10010" -rev> [0,1,0,0,1] -means> [  0,      1,      0,      0,      1  ]
                                      [(-2)^0, (-2)^1, (-2)^2, (-2)^3, (-2)^4] 
    
    那么让我们列出两个列表

    powers = [(-2)^n | n <- [0..]]
    coefficients = reverse.map val $ xs
    
    然后加起来,给出:

    negbin_dezi4 xs = sum $ zipWith (*) powers coefficients
        where powers = [(-2)^n | n <- [0..]]
          coefficients = reverse.map val $ xs
    
    negbin_dezi4 xs=sum$zipWith(*)幂系数
    
    其中powers=[(-2)^n | n您的列表模式匹配语法是向后的。在
    \uu:
    中,第一个参数是列表的头部(一个元素),第二个是列表的尾部(另一个列表)。例如
    x:xs
    匹配,“abc”
    给出
    x='a'
    xs bc“
    。因此
    xs:x
    应该是
    x:xs
    。GHC请求Num[Char]
    实例的原因是比较
    x==0
    (和
    x==1
    )。在这种情况下,它试图将
    x
    String
    =
    =
    =Char
    )的类型与
    0
    的类型相匹配(
    numa=>a
    ),为此,它需要
    String
    Num
    实例

    修正是:
    negbin_dezi(x:xs)n

    请求
    浮点整数
    实例的问题是因为
    (**)
    的类型为
    浮点a=>a->a->a->a
    ,其中
    (^)
    的类型为
    (Num a,Integral b)=>a->b->a
    (即,它被限制为整数幂)

    完成此操作后,您会发现您的算法不起作用,原因如下:

    • 数字0不同于字符
      '0'
      ,您应该将
      x
      与字符
      '0'
      '1'
      进行比较,而不是将数字
      0
      1
      进行比较
    • xs
      已经是一个字符串,因此
      [xs]
      是一个包含字符串的列表,该字符串不是您想要的字符串。删除方括号可以解决此问题
    • 还原的顺序可能是错误的

    另一方面,重复的
    if
    语句表明您的代码可能会出现一些优化。特别是,如果您将空字符串作为
    negbin_dezi
    的一部分处理,则不必对其进行特殊处理。您可以编写如下代码

    negbin_dezi "" _ = 0
    negbin_dezi (x:xs) n 
            | n == '0' = negbin_dezi xs (n+1)
            | n == '1' = (-2)^n + negbin_dezi
    
    (这意味着该函数是“更全面的”,即它是在更多输入上定义的。)

    还有几件事:

    • 代码是“stringtyped”:您的数据被表示为字符串,尽管有更多的结构。布尔值列表(
      [Bool]
      )会更好
    • 该算法可以调整为更干净。对于以下情况,我假设您将其存储为
      “01”=-2
      “001”=4
      ,等等。如果是这样,那么我们知道
      number=a+(-2)*b+(-2)^2*c…=a+(-2)*(b+(-2)*(c+…)
      其中
      a
      b
      c
      ,…是数字。看看这个,我们可以看到括号内的内容实际上与整个表达式相同,只是从第二个数字开始。这很容易用Haskell表达(我使用的是bools的想法列表):

      这就是全部。如果你没有按顺序存储它,那么调用
      reverse
      就可以解决这个问题!(真的很棘手,你可以编写

      negbin = foldr (\x n -> (if x then 1 else 0) + (-2)*n) 0
      
      )

      • convB2D::NegaBinary->Integer convB2D xs|(length xs)==0 =0 |b=='0' = convB2D(drop 1 xs) |b=='1' = val+convB2D(drop 1 xs) |otherwise= error "invalid character " where b=head xs val=(-2)^((length xs)-1) convB2D::负二进制->整数 convB2D xs |(长度xs)==0=0 |b=='0'=convB2D(放置1个X) |b=='1'=val+convB2D(下降1个X) |否则=错误“无效字符” 式中,b=头xs val=(-2)^(长度xs)-1) 为我工作。
        另一方面,我在转换dec->nbin:D时遇到问题。问题和标题“走不同的路”。是更常见的(和可搜索的)术语;特别是negabinary。(如果您将小数点也张贴到(-2)阿迪亚代码,这会有所帮助。)
        powers
        也可以是
        powers=1:map(-2)*)powers
        ,我认为这更有效。@dbaupp打得好。已编辑。谢谢。
        negbin = foldr (\x n -> (if x then 1 else 0) + (-2)*n) 0
        
        convB2D::NegaBinary->Integer convB2D xs|(length xs)==0 =0 |b=='0' = convB2D(drop 1 xs) |b=='1' = val+convB2D(drop 1 xs) |otherwise= error "invalid character " where b=head xs val=(-2)^((length xs)-1)