【问题标题】:Random string of numbers excluding specific digits不包括特定数字的随机数字串
【发布时间】:2011-07-12 18:29:51
【问题描述】:

我正在使用 C# 开发一个 .NET 应用程序,它将生成一个可变长度的随机数字字符串。我想添加一个清单,允许用户选择零到九之间的任意数字组合,并防止它们出现在字符串中。目前,我只是这样做来获取字符串:

do
{
   int num = rnd.Next(10);
   output += num.ToString();
   i++;
}
while (i < stringLength);

我可以想出一种方法来排除选定的数字,一旦它们生成就将其丢弃,而不是增加计数器,但似乎会有一种不那么浪费的算法。该程序将支持生成多个字符串,因此如果用户创建数百万个字符串,我希望将开销保持在最低限度。

奖励:我忘了提到,如果有人可以为我指出此类模式的资源,我也很高兴。在不久的将来,我将大量使用基于参数的随机数,我想学习一些原则,而不是就诸如此类的个别问题提出问题。

【问题讨论】:

  • 喂!完全不是您问题的答案,但是:在 .NET 中使用“+”运算符进行字符串连接很昂贵。那里的 StringBuilder 会更好。抱歉,只是我的一个小问题。
  • Knuth 的计算机编程艺术,尤其是第 4 卷,您可能会觉得有用的参考:www-cs-faculty.stanford.edu/~uno/taocp.html

标签: c# .net random


【解决方案1】:

如果您生成一个允许的字符数组,然后从中选择:

int[] allowedDigits = {1, 2, 3, 6, 7, 0};
var output = new StringBuilder();

do
{
   int num = rnd.Next(allowedDigits.Length);
   output.Append(allowedDigits[num]);
   i++;
}
while (i < stringLength);

显然allowedDigits 是生成的,而不是硬编码的;)

使用StringBuilder 效率更高,您不必明确地使用ToString

【讨论】:

  • 你真的应该知道+=String 是两个在循环中效果很差的东西。
【解决方案2】:
  1. 创建一个长度为 n 的数组,保存 选择的数字。
  2. 生成0到0之间的随机数 n-1,含
  3. 使用随机数作为数组 选择数字的索引。

【讨论】:

  • 这不会导致一个完全由随机数字组成的字符串,这些随机数字被选为不是字符串的一部分吗?还是我误解了第 1 步?
【解决方案3】:
string[] num = new string[9];
int j = 0;
for(int k = 0; k < num.length; k++)
  if (k != numToExclude)
    num[j++] = k.ToString();
}
StringBuilder output = new StringBuilder(stringLength);
do
{
   int n = rnd.Next(10);
   output.Append(num[n]);
   i++;
}
while (i < stringLength);

在上面的代码中,您可以更改num 数据类型char。不确定这是否优化了任何东西。

【讨论】:

    【解决方案4】:
    int [] excludeNum={2 , 3 , 4}; 
    do
    {
       int num = rnd.Next(10);
       if(excludeNum.Contains(num))
          continue;
       output += num.ToString();
       i++;
    }
    while (i < stringLength);
    

    通过使用continue 语句,您可以将控制流更改回while();,而无需增加i

    【讨论】:

      【解决方案5】:

      只是为了一笑而过,这是一种无偿“聪明”的做法:

      int allowedDigits = {1, 3, 5, 4, 9};
      
      //Generate an infinite sequence of numbers, 
      //so be careful not to do foreach over it!
      IEnumerable<int> GenerateNumbers(int max)
      {
         while(true)
         {
            yield return rnd.Next(max);
         }
      }
      
      var filteredNumbers = from num in GenerateNumbers(10)
                            where num in allowedDigits
                            select num;
      
      output = String.Join("", fitleredNumbers.Take(stringLength));
      

      (或类似的词,目前没有编译器可以检查它......)

      不言而喻,这可能效率低下……

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-09
        相关资源
        最近更新 更多