1

我有一些可以编译和工作的代码。然后一些没有。我担心的是第一个版本太臃肿以至于在运行太大的参数时崩溃了,所以我写了第二个版本时考虑到了性能。第二个版本甚至没有编译。请指教。

import System.Environment   (getArgs)
import Data.List            (nub)
import System.Random
import Control.Applicative  ( (<$>) )
import Control.Monad        (replicateM)

randomItem :: [a] -> IO a
randomItem xs = (xs!!)  <$> randomRIO (0, length xs - 1)

genFromMask :: [String] -> IO String
genFromMask = mapM randomItem

genMeSome :: [String] -> Int -> IO [String]
genMeSome mask n = do
  glist <- replicateM (n*10) (genFromMask mask)
  return $ take n $ nub glist

writeIt ::  FilePath -> Int -> [String] -> IO ()
writeIt fi n mask = do
    glist <- genMeSome mask n
   writeFile fi $ unlines glist

maj :: String
maj = ['A'..'Z']

numa :: String
numa = ['0'..'9']


-- | Certaines regions n'utilisent aucune des plages libres
genBra :: [String]
genBra = ["VWXYZ",maj,maj," ",numa,numa,numa,numa]

genAus :: [String]
genAus = [maj,maj,maj," ",numa,numa,numa]

main :: IO ()
main = do
  args <- getArgs
  case args of
    (mo:fi:n:_) -> case mo of
      "aus" -> writeIt fi (read n) genAus
      "bra" -> writeIt fi (read n) genBra
      _     -> error "country is not supported"
    _           -> error "wrong input, format is: genLicensePlate country file number"

这是第二个:

import System.Environment   (getArgs)
import System.Random
import Crypto.Random.AESCtr (makeSystem)
import Control.Applicative  ( (<$>) )
import qualified Data.Vector  as V
import qualified Data.Text    as T
import qualified Data.Text.IO as T

nubV :: V.Vector a -> V.Vector a
nubV va
  | V.null va              = V.empty
  | V.any (== headV) tailV = nubV tailV
  | otherwise              = headV `V.cons` nubV tailV
 where
  headV = V.head va
  tailV = V.tail va

randomItem :: RandomGen g => g -> V.Vector a -> (a,g)
randomItem g xs =
  (xs V.! fst shamble, snd shamble)
 where
  shamble = randomR (0, V.length xs - 1) g

genFromMask :: RandomGen g => g -> V.Vector (V.Vector a) -> V.Vector a
genFromMask g xs =
  if V.null xs
     then V.empty
     else fst paket `V.cons` genFromMask (snd paket) (V.tail xs)
 where
  paket = randomItem g (V.head xs)

genMeSome :: RandomGen g => g -> V.Vector (V.Vector a) -> Int -> V.Vector (V.Vector a)
genMeSome g mask n =
  V.take n $ nubV $ V.replicateM (n*10) (genFromMask g mask)

writeIt :: RandomGen g => g -> FilePath -> Int -> V.Vector (V.Vector a) -> IO ()
writeIt g fi n mask =
   T.writeFile fi $ T.unlines $ T.pack $ V.toList (V.map V.toList $ genMeSome g mask n)

maj   = V.fromList ['A'..'Z']
num a = V.fromList ['0'..'9']
vspa  = V.fromList " "
vtir  = V.fromList "-"

-- | Certaines regions n'utilisent aucune des plages libres
genBra = V.fromList [static,maj,maj,vspa,numa,numa,numa,numa]
 where
  static = V.fromList "VWXYZ"

genAus = V.fromList [maj,maj,maj,vspa,numa,numa,numa]

main :: IO ()
main = do
  g    <- makeSystem
  args <- getArgs
  case args of
    (mo:fi:n:_) -> case mo of
      "aus" -> writeIt g fi (read n) genAus
      "bra" -> writeIt g fi (read n) genBra
      _     -> error "country is not supported"
    _           -> error "wrong input, format is: genLicensePlate country file number"

我正在尝试生成假车牌,以填充匿名数据库。

编辑1:

以下是错误:

genLicensePlate.hs:22:12:
    No instance for (Eq a)
      arising from a use of `=='
    In the first argument of `V.any', namely `(== headV)
    In the expression: V.any (== headV) tailV
    In a stmt of a pattern guard for
               an equation for `nubV':
      V.any (== headV) tailV

genLicensePlate.hs:48:52:
    Couldn't match expected type `Char' with actual type
    Expected type: V.Vector Char
      Actual type: V.Vector [a]
    In the first argument of `V.toList', namely
      `(V.map V.toList $ genMeSome g mask n)'
    In the second argument of `($)', namely
      `V.toList (V.map V.toList $ genMeSome g mask n)'

编辑2:

所以总体思路是使用掩码生成随机字符串。像 myFunc g [['A'..'Z'],['A'..'Z']] 给出 AA 或 ZZ 或 BA 或 FG 等......然后我使用这个函数来制作很多这些字符串基于掩码。之后,我删除重复项并根据需要获取尽可能多的数量(因为即使有重复项我也可以生成 10 倍于所要求的数字)。最后我把它放在一个文件上。

我希望它更清楚。

亲切的问候,萨尔

4

1 回答 1

3

nubV需要一个Eq约束,因为它比较元素(但你真的应该使用一个SetHashSet左右来获得更好的算法)

nubV :: Eq a => V.Vector a -> V.Vector a
nubV va
  | V.null va              = V.empty
  | V.any (== headV) tailV = nubV tailV
  | otherwise              = headV `V.cons` nubV tailV
 where
  headV = V.head va
  tailV = V.tail va

而在writeIt,你缺少一个map

writeIt :: RandomGen g => g -> FilePath -> Int -> V.Vector (V.Vector a) -> IO ()
writeIt g fi n mask =
   T.writeFile fi $ T.unlines $ map T.pack $ V.toList (V.map V.toList $ genMeSome g mask n)
                            --  ^^^

Char因为您获得了from的列表列表V.toList (V.map V.toList $ genMeSome g mask n)

这修复了两个报告的错误。

于 2013-02-27T23:29:09.623 回答