生成所有唯一的银行帐号

时间:2015-01-18 11:26:08

标签: c#

我有一个检查数字是否可以被11整除的方法。

public bool IsBankAccount(string BankNumber)
{
    int factor = 9;
    int restult = 0;

    try
    {
        if ((BankNumber.Length == 9))
        {
            for (int i = 0; i < BankNumber.Length; i++)
            {
                 restult += int.Parse(BankNumber.Substring(i, 1)) * factor;
                 factor -= 1;
            }
            return (restult % 11 == 0);

        }
        else
        {
            //Wrong length;
            return false;    
        }    
    }
    catch (Exception)
    {    
        return false;
    }    
}

但如何生成所有第一个银行帐号,即第一个号码是:

100000002 =因为9 * 1 + 8 * 0 + 7 * 0 + 6 * 0 + 5 * 0 + 4 * 0 + 3 * 0 + 2 * 0 + 1 * 2 = 11

如果您想要所有银行帐号。这是一个9位数的1000万个数字。所以1000 000 000/11 = 90909090.9 11-11个数字

我只是尝试不同的解决方案。

但如果我试试这个:

static readonly int[] multipliers = {9, 8, 7, 6, 5, 4, 3, 2, 1};
        static void Main(string[] args)
        {
             var bansAsStrings = BANS().Take(100).Select(ban => ban.ToString());
            foreach (var ban in bansAsStrings)
            {
                Console.WriteLine(ban);
            }




            Console.ReadKey();
        }


        static IEnumerable<int> BANS()
        {
            int[] digits = { 1, 0, 0, 0, 0, 0, 0, 0, 2 };


            int carryFlag = 0;
            do
            {
                int sum = digits.Zip(multipliers, (d, m) => d * m)
                                .Sum();

                if (sum % 11 == 0)
                    yield return sum;

                int digitIndex = digits.Length - 1;
                do
                {
                    digits[8] += 1 + carryFlag;
                    if (digits[8] == 10)
                    {
                        digits[digitIndex--] = 0;
                        carryFlag = 1;
                    }
                    else
                        carryFlag = 0;
                }
                while (carryFlag == 1 && digitIndex >= 0);
            }
            while (carryFlag == 0);

            yield break;
        }

输出为11 100次。

我现在就这样:

static void Main(string[] args)
        {
            const int linesPerFile = 10;
            const string destinationFileName = @"G:\Folder\File-Part-{0}.txt";
            //string fileName = "File";


            foreach (var bank in BankAcoutNumbers.BANS.Take(200))
            {



                var fileCounter = 0;
                var destiNationFile = new StreamWriter(string.Format(destinationFileName, fileCounter + 1));
                try
                {

                   // foreach (var bank in BankAcoutNumbers.BANS.Take(100))
                    //{
                        var lineCounter = 0;
                        string line;

                        while ((line = destiNationFile.NewLine) != null )
                        {
                            if (lineCounter >= linesPerFile)
                            {
                                lineCounter = 0;
                                fileCounter++;
                                destiNationFile.Dispose();
                                destiNationFile = new StreamWriter(string.Format(destinationFileName, fileCounter + 1));

                            }

                            destiNationFile.WriteLine(bank);
                            lineCounter++;
                        }
                    //}


                }
                catch (Exception)
                {

                    throw;
                }
            }


            // Keep the console window open in debug mode.
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();
        }

    }

但现在每次写下第一个值:1000 000 02

我现在就这样:

static void Main(string [] args)     {

    const int linesPerFile = 10;
    const string destinationFileName = @"G:\Folder\File-Part-{0}.txt";
    //string fileName = "File";
    var maxNumberOfFiles = 20;            



        var fileCounter = 0;
        var destiNationFile = new StreamWriter(string.Format(destinationFileName, fileCounter + 1));
        try
        {

            // foreach (var bank in BankAcoutNumbers.BANS.Take(100))
            //{
            var lineCounter = 0;
            string line;

            while (fileCounter < maxNumberOfFiles)
            {
                foreach (var bank in BankAcoutNumbers.BANS.Take(200))
                {
                    if (lineCounter >= linesPerFile)
                    {
                        lineCounter = 0;
                        fileCounter++;
                        destiNationFile.Dispose();
                        destiNationFile = new StreamWriter(string.Format(destinationFileName, fileCounter + 1));

                    }

                    destiNationFile.WriteLine(bank);
                    lineCounter++;
                }

                fileCounter++;
                //}


            }
        }
        catch (Exception)
        {

            throw;
        }



    // Keep the console window open in debug mode.
    System.Console.WriteLine("Press any key to exit.");
    System.Console.ReadKey();
}

但我不喜欢你每次都要计算MaxFiles的数量。还有其他方法吗?感谢

以下是更新:

static void Main(string [] args)     {

    const int linesPerFile = 10;
    string path = @"G:\Folder";
    const string destinationFileName = @"G:\Folder\File-Part-{0}.txt";
    //string fileName = "File";
    var maxNumberOfFiles = 10;
    Stopwatch timer = new Stopwatch();



        var fileCounter = 0;

        if (!Directory.Exists(path))
        {
           DirectoryInfo di = Directory.CreateDirectory(path);
        }

        var destiNationFile = new StreamWriter(string.Format(destinationFileName, fileCounter + 1));
        try
        {

            // foreach (var bank in BankAcoutNumbers.BANS.Take(100))
            //{
            var lineCounter = 0;
            string line;

            while (fileCounter <= maxNumberOfFiles)
            {
                timer.Start();
                foreach (var bank in BankAcoutNumbers.BANS.Take(100))
                {
                    if (lineCounter % linesPerFile == 0)
                    {
                        //lineCounter = 0;
                        destiNationFile.Flush();                                
                        destiNationFile.Dispose();
                        destiNationFile = new StreamWriter(string.Format(destinationFileName, fileCounter + 1));
                        fileCounter++;
                    }

                    destiNationFile.WriteLine(bank);
                    lineCounter++;



                }

                fileCounter++;

                //}


            }


            timer.Stop();
            // Console.WriteLine(BankAcoutNumbers.BANS.Count());
            Console.WriteLine(timer.Elapsed.Seconds);
        }
        catch (Exception)
        {

            throw;
        }



    // Keep the console window open in debug mode.

    System.Console.WriteLine("Press any key to exit.");
    System.Console.ReadKey();
}

但要获取文件名,如下所示:Nr [文件中的第一个数字] - [文件中的最后一个数字] .txt谢谢

我现在就这样:

 static void Main(string[] args)
        {


            const int linesPerFile = 10;
            string path = @"G:\Folder";
            const string destinationFileName = @"G:\Folder\File-Part-{0}.txt";
            var bans = BankAcoutNumbers.BANS;
            var counter = 100;
            string tempFile;
            //string fileName = "File";
            var maxNumberOfFiles = 10;
            Stopwatch timer = new Stopwatch();



                var fileCounter = 0;

                if (!Directory.Exists(path))
                {
                   DirectoryInfo di = Directory.CreateDirectory(path);
                }

                var destiNationFile = new StreamWriter(string.Format(destinationFileName, fileCounter + 1));
                try
                {

                    // foreach (var bank in BankAcoutNumbers.BANS.Take(100))
                    //{
                    var lineCounter = 0;
                    string line;

                    while (fileCounter <= maxNumberOfFiles)
                    {
                        timer.Start();
                        foreach (var bank in bans)
                        {
                            if (--counter == 0)
                            {
                                break;
                            }

                                if (lineCounter % linesPerFile == 0)
                                {
                                    //lineCounter = 0;
                                    destiNationFile.Flush();
                                    destiNationFile.Dispose();
                                    destiNationFile = new StreamWriter(string.Format(destinationFileName, fileCounter + 1));
                                    fileCounter++;
                                }

                                destiNationFile.WriteLine(bank);
                                lineCounter++;





                            fileCounter++;

                            //}


                        }
                    }


                    timer.Stop();
                    // Console.WriteLine(BankAcoutNumbers.BANS.Count());
                    Console.WriteLine(timer.Elapsed.Seconds);
                }
                catch (Exception)
                {

                    throw;
                }



            // Keep the console window open in debug mode.

            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();
        }

但是每次十个文件的最后一个文件都是空的。

如何获取文件名?

static void Main(string [] args)         {

        const int linesPerFile = 10;
        string path = @"G:\Folder";

        //string fileName = string.Format("{0}{1}-", part[0], part[part.Count - 1]);
        var bans = BankAcoutNumbers.BANS;
        string tempFile;
        const int MAX_FILES = 10;
        const int BANS_PER_FILE = 10;
        int bansCounter = 0;
        var part = new List<int>();
        string fileName = string.Format("{0}-{1}", part[0], part[part.Count - 1]);

        var maxNumberOfFiles = 10;
        Stopwatch timer = new Stopwatch();



            var fileCounter = 0;

            if (!Directory.Exists(path))
            {
               DirectoryInfo di = Directory.CreateDirectory(path);
            }

            //var destiNationFile = new StreamWriter(string.Format(fileName, fileCounter + 1));
            try
            {

                // foreach (var bank in BankAcoutNumbers.BANS.Take(100))
                //{
                var lineCounter = 0;
                string line;

                while (fileCounter <= maxNumberOfFiles)
                {
                    timer.Start();
                    foreach (var bank in BankAcoutNumbers.BANS)
                    {
                        part.Add(bank);
                       if(++bansCounter >= BANS_PER_FILE)
                        {
                            //string fileName2 = string.Format("{0}-{1}", part[0], part[part.Count - 1]);
                            var destinationFile = new StreamWriter(fileName);
                            //destiNationFile = new StreamWriter(fileName);
                            Console.WriteLine("NR{0}", fileName);
                            foreach (var partBan in  part )                                
                                Console.WriteLine(partBan);
                            part.Clear();
                            bansCounter = 0;

                            if (++fileCounter >= MAX_FILES)
                           break;



                            //lineCounter = 0;
                            //destiNationFile.Flush();                                
                            //destiNationFile.Dispose();
                            //destiNationFile = new StreamWriter(string.Format(fileName, fileCounter + 1));
                            //fileCounter++;
                        }

                        //destiNationFile.WriteLine(bank);
                        //lineCounter++;



                    }

                    //fileCounter++;

                    //}


                }


                timer.Stop();
                // Console.WriteLine(BankAcoutNumbers.BANS.Count());
                Console.WriteLine(timer.Elapsed.Seconds);
            }
            catch (Exception)
            {

                throw;
            }



        // Keep the console window open in debug mode.

        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }

3 个答案:

答案 0 :(得分:3)

public static IEnumerable<int> BANS
{
    get
    {
        int[] digits = { 1, 0, 0, 0, 0, 0, 0, 0, 2 };

        int carryFlag = 0;
        do
        {
            int sum = digits.Select((d, i) => d * (9 - i))
                            .Sum();

            if (sum % 11 == 0)
                yield return digits.Aggregate(0, (accumulator, digit) => accumulator * 10 + digit);

            int digitIndex = digits.Length - 1;
            do
            {
                digits[digitIndex] += 1;
                if (digits[digitIndex] == 10)
                {
                    digits[digitIndex--] = 0;
                    carryFlag = 1;
                }
                else
                    carryFlag = 0;
            }
            while (digitIndex >= 0 && carryFlag == 1);
        }
        while (carryFlag == 0);

        yield break;
    }
}

Console.WriteLine(BANS.Count())给了81818182 BAN。虚拟机中的计算时间约为5分钟。

前10个值是:

foreach (var ban in BANS.Take(10))
    Console.WriteLine(ban);
----------------------------------
100000002
100000010
100000029
100000037
100000045
100000053
100000061
100000088
100000096
100000118

关于第二个问题:

static void Main(string[] args)
{
    const int MAX_FILES = 10;
    const int BANS_PER_FILE = 10;

    int filesCounter = 0;
    int bansCounter = 0;
    var part = new List<int>();
    foreach (var ban in BANS)
    {
        part.Add(ban);

        if (++bansCounter >= BANS_PER_FILE)
        {
            string fileName = string.Format("{0}-{1}.txt", part[0], part[part.Count - 1]);
            Console.WriteLine("Filename '{0}'", fileName);
            foreach (var partBan in part)
                Console.WriteLine(partBan);

            part.Clear();
            bansCounter = 0;

            if (++filesCounter >= MAX_FILES)
                break;
        }

    }
}

答案 1 :(得分:0)

这是你想要的吗?

var bankAccounts = new List<string>(100);
for(long i = 100000000; bankAccounts.Count < 100;i++)   
{
    var stringNumber = i.ToString();
    if (IsBankAccount(stringNumber))
        bankAccounts.Add(stringNumber);
}

这也可以通过LINQ完成,如下所示。

var accounts = Enumerable.Range(100000000, 2000) // 2000 is a guess, there's sure 100 values divisible by 11 in that range
                         .Select(n => n.ToString())
                         .Where(IsBankAccount)
                         .Take(100)
                         .ToList();

由于银行帐户中只有数字,因此您可以在没有字符串转换和字符串操作的情况下执行此操作。

要获取所有这些内容,请将2000替换为899999999,但即使您执行.AsParallel()也需要很长时间才能完成,因为该算法确实无效。

基于ie的评论,快速算法可能看起来像这样,但它仍然非常耗费内存。

var nums = new List<string>();
for (int i = 100000002; i < 1000000000; i += 11)
    nums.Add(i.ToString());

答案 2 :(得分:0)

您可以通过计算最后一位数作为校验位来枚举可能的数字:

static void Main(string[] args)
{
    foreach (var num in GetMod11Sequence(10000000, 100000000).Take(100))
    {
        if (!CheckMod11CheckChar(num))
        {
            throw new InvalidOperationException();
        }
        else
        {
            Console.WriteLine(num);
        }
    }
}

private static IEnumerable<string> GetMod11Sequence(int start, int stop)
{
    //Contract.Requires(start > 0);
    //Contract.Requires(stop > start);
    //Contract.Requires(stop < 1000000000);

    for (int c = start; c < stop; c++)
    {
        string number = c.ToString();
        char check;
        if (TryCalculateMod11CheckChar(number, out check))
        {
            yield return number + check;
        }
    }
}

private static bool CheckMod11CheckChar(string number)
{
    //Contract.Requires(number != null);
    //Contract.Requires(number.All(c => char.IsDigit(c)));

    int factor = number.Length;
    int sum = 0;
    for (int i = 0; i < number.Length; i++)
    {
        int cval = number[i] - '0';

        sum += cval * factor;
        factor--;
    }

    return sum % 11 == 0;
}

private static bool TryCalculateMod11CheckChar(string number, out char checkDigit)
{
    //Contract.Requires(number != null);

    int factor = number.Length + 1;
    int sum = 0;
    for (int i = 0; i < number.Length; i++)
    {
        int cval = number[i] - '0';

        sum += cval * factor;
        factor--;
    }
    //Contract.Assert(factor == 1);

    int delta = sum % 11;
    if (delta == 1)
    {
        // I cannot add 10, so this number is unavailable
        checkDigit = '!';
        return false;
    }
    else
    {
        if (delta == 0)
        {
            checkDigit = '0';
        }
        else
        {
            checkDigit = (11 - delta).ToString()[0];
        }
        return true;
    }
}