3

如何以列表理解形式表达 {2n+3m+1|n,m∈N}?N是自然数的集合,包括0。

4

6 回答 6

12

不久:

1:[3..]
于 2009-04-17T09:14:45.573 回答
8

不是 {2n+3m+1|n,m ∈ ℕ} = ℕ - {0,2} 吗?

于 2009-04-17T08:44:30.327 回答
7

以下 Haskell 函数将为您提供两个列表中的所有对,即使其中一个或两个是无限的。每对只出现一次:

allPairs :: [a] -> [b] -> [(a, b)]
allPairs _ [] = []
allPairs [] _ = []
allPairs (a:as) (b:bs) = 
   (a, b) : ([(a, b) | b <- bs] `merge` 
             [(a, b) | a <- as] `merge` 
             allPairs as bs)
  where merge (x:xs) l = x : merge l xs
        merge []     l = l

然后你可以把你的清单写成

[2 * n + 3 * m + 1 | (n,m) <- allPairs [0..] [0..] ]

要了解它的工作原理,请绘制一个无限的四分之一平面,然后查看结果

take 100 $ allPairs [0..] [0..]
于 2009-04-18T03:09:28.687 回答
4

[2*n + 3*m +1 | m <- [0..], n <- [0..]]不会工作,因为它从所有的 开始m = 0并经过n,然后有m = 1并经过所有的 n 等。但只是m = 0部分是无限的,所以你永远不会到达 m = 1 或 2 或 3 等。所以[2*n + 3*m +1 | m <- [0..], n <- [0..]]与 完全相同[2*n + 3*0 +1 | n <- [0..]]

要生成所有这些,您要么需要像用户 vartec 和 Hynek -Pichi- Vychodil 一样意识到,您想要的数字集只是自然数 - {0,2}。或者您需要以某种方式枚举所有对 (m,n) 以使 m,n 为非负数。一种方法是沿着每个相同的“对角线”走m + n。所以我们从 where 的数字开始m + n = 0,然后是 where的数字m + n = 1,等等。这些对角线中的每一个都有有限数量的对,所以你总是会继续下一个,所有对 (m,n) 最终将是算了。

如果我们让i = m + nand j = m,则[(m, n) | m <- [0..], n <- [0..]]变为[(j, i - j) | i <- [0..], j <- [0..i]]

所以对你来说,你可以做

[2*(i-j) + 3*j +1 | i <- [0..], j <- [0..i]]

(当然,此方法也会为您生成重复项,因为有多个 (m,n) 对在您的表达式中生成相同的数字。)

于 2009-04-17T17:38:20.417 回答
0

您可以尝试枚举所有整数对。此代码基于加州大学伯克利分校描述的枚举(不包括 0)

data Pair=Pair Int Int deriving Show

instance Enum Pair where
    toEnum n=let l k=truncate (1/2 + sqrt(2.0*fromIntegral k-1))
                 m k=k-(l k-1)*(l k) `div` 2
             in 
               Pair (m n) (1+(l n)-(m n))
    fromEnum (Pair x y)=x+((x+y-1)*(x+y-2)) `div` 2

但是您可以使用另一个枚举。

然后你可以这样做:

[2*n+3*m+1|Pair n m<-map toEnum [1..]]
于 2009-04-19T20:41:24.547 回答
0

我的 0.2:

trans = concat [ f n | n <- [1..]]
 where 
  mklst x = (\(a,b) -> a++b).unzip.(take x).repeat
  f n | n `mod` 2 == 0 = r:(mklst n (u,l))
      | otherwise      = u:(mklst n (r,d))
  u = \(a,b)->(a,b+1)
  d = \(a,b)->(a,b-1)
  l = \(a,b)->(a-1,b)
  r = \(a,b)->(a+1,b)

mkpairs acc (f:fs) = acc':mkpairs acc' fs
                  where acc' = f acc
allpairs = (0,0):mkpairs (0,0) trans          
result = [2*n + 3*m + 1 | (n,m) <- allpairs]
于 2009-12-24T23:37:12.310 回答