【问题标题】:Random Number Array [duplicate]随机数数组 [重复]
【发布时间】:2014-05-18 21:50:13
【问题描述】:

我正在尝试为基本银行功能创建一个控制台应用程序。我了解随机数生成器的工作原理,但考虑到生成的随机数代表用户个性化的 PIN 码,我需要设置一个数组以使随机数不重复。我将如何在我当前的代码中实现这一点?

class BankAccount
{
    private string firstName;
    private string lastName;
    private int accountNumber;
    private decimal balance;
    static public int customers = 0;
    private int pinNumber;

    public decimal Balance
    {
        get
        {
            return balance;
        }
        set
        {
            if (value >= 0)
                balance = value;
            else
            {
                Console.WriteLine("There will be an overdraft fee of $10.00.");
                balance = value - 10;
            }
        }
    }

    public string FirstName
    {
        get
        {
            return firstName;
        }
    }

    public string LastName
    {
        get
        {
            return lastName;
        }
    }

    public int AccountNumber
    {
        get
        {
            return accountNumber;
        }
    }

    public int PinNumber
    {
        get
        {
            return pinNumber;
        }
    }

    public BankAccount(string firstNameValue, string lastNameValue)
    {
        firstName = firstNameValue;
        lastName = lastNameValue;
        accountNumber = customers + 1;
        Random pin = new Random();
        pinNumber = pin.Next(1111, 9999);
        Balance = 0;
        customers++;
    }

    public BankAccount()
    {
        Balance = 0;
        customers++;
    }

    public void Credit(decimal amount)
    {
        Balance = Balance + amount;
    }

    public void Debit(decimal amount)
    {
        if (amount > Balance)
            Console.WriteLine("Debit amount exceeded account balance.");
        Balance = Balance - amount;
    }

    public static decimal AverageBalance(BankAccount[] accounts)
    {
        int count = 0;
        decimal total = 0;
        for (int i = 0; i < accounts.Length; i++)
        {
            if (accounts[i] != null)
            {
                total += accounts[i].Balance;
                count++;
            }
        }
        return total / count;
    }
}

【问题讨论】:

  • 不想听起来刺耳:但是有这样一个问题我建议不要写银行应用程序!!!
  • 我不是专业程序员。我还在读第一年。这只是我们必须完成的任务的一部分。我很谦虚地说我有很多东西要学,我只是试着边做边学。这是我在作业中遇到的唯一问题。
  • 好吧,如果您“仍在学习”,那么“告诉”解决方案的意义何在?做一些研究,你就会明白!发现后,你永远不会忘记。说了这么多,两周后你就记不起来了……

标签: c# arrays random


【解决方案1】:

当您执行new Random() 时,.Net 使用当前时间作为种子。如果您在短时间内多次执行此操作,您将生成相同的随机数字符串。您可能只想在BankAccount 中创建一个static Random 变量。

static Random random = new Random();

// later, in the constructor
pinNumber = random.Next(0, 10000); // 0 <= pinNumber < 10000

我更改了Next 上的范围,以便它将在整个范围内生成。

【讨论】:

  • 谢谢,但是如何使用数组来防止这种重复?
  • @user3504400(假设这有点像真实的银行场景)你不需要。两个人可以拥有相同的 PIN 码。但如果你是随机生成它们,你就不想给它们相同的 PIN 码。
【解决方案2】:

这个方法用不同的随机数初始化一个数组。我没有测试它,但它应该可以工作。 创建一个数组,使用下面的代码对其进行初始化,然后将其传递给您的方法。

public void SetValues(int[] array)
    {
        Random randomNumber = new Random();

        for (int i = 0; i < array.Length; i++)
        {
            bool distinctNumber = true;
            int number = randomNumber.Next(1, 100);
            for (int j = 0; j < i; j++)
            {
                if (number == array[j])
                {
                    distinctNumber = false;
                    break;
                }
            }
            if ( distinctNumber )      
                array[i] = number;
            else
                --i;    
        }
    }

【讨论】:

    【解决方案3】:

    虽然我不理解对 PIN 码中重复数字的担忧,但解决方案应该非常简单。您的数组将仅包含很少(四)位数字,因此检查数字是否重复没有问题。最简单的方法是使用 Contains 方法,并且仅在数字唯一时追加。但是,包含将查看数组中的所有数字,因此您应该将其初始化为不允许的值(负值),或者使用列表构建它。

    Random rnd = new Random();
    
    var pin = new[] {-1, -1, -1, -1};
    
    for(var i = 0; i < pin.length; i++)
       int nextDigit = rnd.Next(0, 10);
       while (pin.contains(nextDigit)){ nextDigit + rnd.Next(0, 10); }
       pin[i] = nextDigit;
    }
    

    【讨论】:

      【解决方案4】:

      通过在Fisher-Yates shuffle的基础上借用this excellent answer的扩展方法,可以相对干净地完成。

      首先定义一个扩展方法来打乱给定的List&lt;T&gt;

      public static void Shuffle<T>(this IList<T> list)  
      {  
          Random rng = new Random();  
          int n = list.Count;  
          while (n > 1) {  
              n--;  
              int k = rng.Next(n + 1);  
              T value = list[k];  
              list[k] = list[n];  
              list[n] = value;  
          }  
      }
      

      然后定义函数以生成由不同数字组成的 PIN:

      公共 IEnumerable GeneratePIN() {

          var pinDigits = new List<int>(Enumerable.Range(0,10));
          pinDigits.Shuffle();
          return pinDigits.Take(4);
      

      }

      或者,作为一个更好的选择,您还可以使用更通用的引脚生成函数从任意类型生成任意长度的引脚。

      public static IEnumerable<T> GeneratePIN<T>(IEnumerable<T> valueRange, int length)
      {
          var pinValues = new List<T>(valueRange);
          pinValues.Shuffle();
          return pinValues.Take(length);
      }
      

      也就是说,值得一提的是,将 PIN 限制为不同的值会将可能的 PIN 数量从 10000 减少到 5040,从而大大降低了安全性。

      【讨论】:

        猜你喜欢
        • 2011-05-21
        • 1970-01-01
        • 2016-05-05
        • 1970-01-01
        • 2018-07-03
        • 2015-08-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多