我创建一个随机数,然后检查它是否存在于数据库表中。如果确实如此,我会生成另一个并再次检查,以下工作会如何?
public int GenerateNumber()
{
Random r = new Random();
int num = r.Next(1000);
//Psuedo-code
if(num is in table)
GenerateNumber();
return num;
}
似乎基于下面的答案,这里应该避免递归,我应该自动增加数字,所以一个好的选择是开始自动增量为1,填充为0,直到长度为8个字符或者以10,000,000开始。
此外,如果数据类型必须是varchar(8),该怎么办?如何自动递增数字,但是将其存储在varchar(8)中?
答案 0 :(得分:6)
你的方法存在很多问题已被其他人解决,所以相反我会回答你应该问的问题,但不会:
为了正确使用递归,问题必须具备哪些特征?
您不得使用递归,除非您的解决方案展示所有以下特征:
您的示例代码展示了 none 这些特征;使用递归要求您展示所有这些特征,所以在任何情况下都不应该使用递归。
让我举一个例子,通过递归很好地解决 的问题:
树是空的或由左右子树组成;树永远不会包含循环。空树的高度为零;非空树的高度是从根到“最深”空子树的最长路径的长度。编写一个确定树高的方法,假设高度小于200。
这个问题展示了可以通过递归解决的问题的所有特征,因此我们可以这样做。每个递归程序都有这样的模式:
让我们这样做:
int Height(Tree tree)
{
// Trivial case:
if (tree.IsEmpty) return 0;
// Non-trivial case: reduce the problem to two smaller problems:
int leftHeight = Height(tree.Left);
int rightHeight = Height(tree.Right);
int height = Math.Max(leftHeight, rightHeight) + 1;
return height;
}
答案 1 :(得分:5)
这不是需要通过递归解决的问题。更不用说如果你的数据库中有一些数字很多,而且循环很多次,你很快就会出现堆栈溢出错误。为什么不将其更改为迭代函数:
public int GenerateNumber()
{
Random r = new Randon();
int num = r.Next(1000);
while(num is in database)
{
num = r.Next(1000);
}
return num;
}
一种不同的方法,而我在这里
为什么不在这些值之间实现一些传递差异?即:第一个数字是一个,然后是两个等等。然后您需要做的就是获取最新的条目,然后添加一个。无需持续不断地进行数据库查询。
答案 2 :(得分:0)
这可能会导致非常糟糕的表现。使用,例如,Guid,用于此
var rand = Guid.NewGuid().ToString()
答案 3 :(得分:0)
不完全。
if (num is in table)
return GenerateNumber();
else
return num;
会起作用,但循环更简单/更安全:
int num;
do
{
num = r.Next(1000);
} while (num is in table);
return num;
答案 4 :(得分:0)
不,不会。你需要再次调用GenerateNumber获得的数字。
public int GenerateNumber()
{
Random r = new Randon();
int num = r.Next(1000);
//Psuedo-code
if(num is in table)
num = GenerateNumber(); //num = added.
return num;
}
现在你不需要递归地解决这个问题,而在C#中这不是一个好主意,因为C#不像其他语言那样进行尾部优化(它不会改变对迭代的递归调用)你在编译期间)。这可以工作,但是你在堆栈上做了额外的工作,你可能会遇到堆栈溢出错误。但是,既然你问过,这就是你修复代码的方法。
您可以通过执行以下操作轻松将其更改为不使用递归:
while(num is in table){ //I always use brackets to be clear.
num = r.Next(1000);
}
答案 5 :(得分:0)
使用迭代来避免因StackOverFlow异常而崩溃,如果你的表格足够大,这将不可避免地发生。
public int GenerateNumber()
{
bool match = false;
while (!match) {
Random r = new Randon();
int num = r.Next(1000);
//Psuedo-code
if(num is not in table)
//insert
}
return num;
}
答案 6 :(得分:0)
您没有指定数据库是什么。如果它只是内存中使用过的数字列表,那么您的代码可以像这样完成:
private HashSet<int> _usedNumbers = new HashSet<int>();
Random r = new Random(); //Search "Random is not random" on SO to see why I moved this out here.
public int GenerateNumber()
{
int MaxNum = 1000;
int num = r.Next(MaxNum);
if(_usedNumbers.Count == MaxNum)
throw new Exception("I ran out of numbers :(");
while(_usedNumbers.Add(num) == false) //Add will return false if the number already was used.
{
num = r.Next(MaxNum );
}
return num;
}