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