生成充满唯一整数的数组的当前代码崩溃
Current code to generate array filled with unique ints crashes
(这是一个图书馆)
调用函数 GetUniqueInt 时使用 (5, 5) 作为变量。
目前,该代码将使 unity 完全停止,或者使我的 PC 因内存溢出错误而崩溃。
有没有人知道我如何防止它崩溃或导致它崩溃的原因?
using UnityEngine;
namespace MajorSolution
{
public static class MajorMath
{
public static int[] GetUniqueInt(int intCount, int intLength)
{
int[] returnValue = new int[intCount];
int[] temp = new int[intLength];
for (int a = 0; a < intCount; a++)
{
string create = new string("create".ToCharArray());
switch (create)
{
case "create":
returnValue[a] = GetRandomInt(intCount);
goto case "check";
case "check":
bool alreadyTaken = false;
for (int c = 0; c < returnValue.Length - 1; c++)
{
if (returnValue[a] == returnValue[c])
{
// Already Taken!
alreadyTaken = true;
}
}
if (!alreadyTaken)
{
break;
}
else
{
goto case "create";
}
}
}
Debug.Log(returnValue);
return returnValue;
}
public static int GetRandomInt(int intCount)
{
int[] storage = new int[intCount];
int returnValue = 0;
for (int i = 0; i < intCount; i++)
{
storage[i] = (Mathf.FloorToInt(Random.Range(0, 9)) * (int)Mathf.Pow(10,i));
returnValue += storage[i];
}
return returnValue;
}
}
}
编辑 我刚刚意识到我没有准确回答为什么它让 PC 停止的问题,因为代码中有一个无限循环。
问题出现在以下代码行中,请注意发生了什么。
case "create":
returnValue[a] = GetRandomInt(intCount);
goto case "check";
在上面的代码块中,您生成了一个数字并将其放入 returnValue
数组中。现在你跳进你的"check"块
case "check":
bool alreadyTaken = false;
for (int c = 0; c < returnValue.Length - 1; c++)
{
if (returnValue[a] == returnValue[c])
{
// Already Taken!
alreadyTaken = true;
}
}
在此代码块中,您将遍历整个 returnValue
数组,包括您刚刚插入其中的值。基本上,您是在遍历数组,询问您刚刚放入数组中的值是否在数组中。
在不知道您尝试使用这些方法做什么的情况下,我将通过一些小的清理提出一个简单的修复建议
public static int[] GetUniqueInt(int count, int length)
{
var returnValue = new int[count];
var values = new HashSet<int>(); // Used to track what numbers we have generated
for (int i = 0; i < count; ++i)
{
// Generate the number and check to be sure we haven't seen it yet
var number = GetRandomInt(length);
while(values.Contains(number)) // This checks if the number we just generated exists in the HashSet of seen numbers
{
// We get here if the HashSet contains the number. If we have
// seen the number then we need to generate a different one
number = GetRandomInt(length);
}
// When we reach this point, it means that we have generated a new unique number
// Add the number to the return array and also add it to the list of seen numbers
returnValue[a] = number;
values.Add(number); // Adds the number to the HashSet
}
Debug.Log(returnValue);
return returnValue;
}
我最终删除了 intLength
的使用,但从您发布的代码中它仅用于声明一个 temp
数组,而该数组本身从未使用过。基于此,我将其完全删除。
根据您的评论,我更新了修复程序以使用 intLength
。我做了另一个小改动。我从 count
和 length
的变量名中删除了 int
。匈牙利表示法在 C# 代码中不太常见。就个人而言,我觉得没有匈牙利符号的代码更清晰易读。关键是使用好的变量名来表达意图或使其更容易理解。在这种情况下,count
是您要返回的数字的计数(读取总数),length
是数字的长度。您甚至可以考虑将其重命名为 numberOfDigits
以更清楚地表明您将创建一个包含该位数的随机数。
(这是一个图书馆)
调用函数 GetUniqueInt 时使用 (5, 5) 作为变量。
目前,该代码将使 unity 完全停止,或者使我的 PC 因内存溢出错误而崩溃。
有没有人知道我如何防止它崩溃或导致它崩溃的原因?
using UnityEngine;
namespace MajorSolution
{
public static class MajorMath
{
public static int[] GetUniqueInt(int intCount, int intLength)
{
int[] returnValue = new int[intCount];
int[] temp = new int[intLength];
for (int a = 0; a < intCount; a++)
{
string create = new string("create".ToCharArray());
switch (create)
{
case "create":
returnValue[a] = GetRandomInt(intCount);
goto case "check";
case "check":
bool alreadyTaken = false;
for (int c = 0; c < returnValue.Length - 1; c++)
{
if (returnValue[a] == returnValue[c])
{
// Already Taken!
alreadyTaken = true;
}
}
if (!alreadyTaken)
{
break;
}
else
{
goto case "create";
}
}
}
Debug.Log(returnValue);
return returnValue;
}
public static int GetRandomInt(int intCount)
{
int[] storage = new int[intCount];
int returnValue = 0;
for (int i = 0; i < intCount; i++)
{
storage[i] = (Mathf.FloorToInt(Random.Range(0, 9)) * (int)Mathf.Pow(10,i));
returnValue += storage[i];
}
return returnValue;
}
}
}
编辑 我刚刚意识到我没有准确回答为什么它让 PC 停止的问题,因为代码中有一个无限循环。
问题出现在以下代码行中,请注意发生了什么。
case "create":
returnValue[a] = GetRandomInt(intCount);
goto case "check";
在上面的代码块中,您生成了一个数字并将其放入 returnValue
数组中。现在你跳进你的"check"块
case "check":
bool alreadyTaken = false;
for (int c = 0; c < returnValue.Length - 1; c++)
{
if (returnValue[a] == returnValue[c])
{
// Already Taken!
alreadyTaken = true;
}
}
在此代码块中,您将遍历整个 returnValue
数组,包括您刚刚插入其中的值。基本上,您是在遍历数组,询问您刚刚放入数组中的值是否在数组中。
在不知道您尝试使用这些方法做什么的情况下,我将通过一些小的清理提出一个简单的修复建议
public static int[] GetUniqueInt(int count, int length)
{
var returnValue = new int[count];
var values = new HashSet<int>(); // Used to track what numbers we have generated
for (int i = 0; i < count; ++i)
{
// Generate the number and check to be sure we haven't seen it yet
var number = GetRandomInt(length);
while(values.Contains(number)) // This checks if the number we just generated exists in the HashSet of seen numbers
{
// We get here if the HashSet contains the number. If we have
// seen the number then we need to generate a different one
number = GetRandomInt(length);
}
// When we reach this point, it means that we have generated a new unique number
// Add the number to the return array and also add it to the list of seen numbers
returnValue[a] = number;
values.Add(number); // Adds the number to the HashSet
}
Debug.Log(returnValue);
return returnValue;
}
我最终删除了 intLength
的使用,但从您发布的代码中它仅用于声明一个 temp
数组,而该数组本身从未使用过。基于此,我将其完全删除。
根据您的评论,我更新了修复程序以使用 intLength
。我做了另一个小改动。我从 count
和 length
的变量名中删除了 int
。匈牙利表示法在 C# 代码中不太常见。就个人而言,我觉得没有匈牙利符号的代码更清晰易读。关键是使用好的变量名来表达意图或使其更容易理解。在这种情况下,count
是您要返回的数字的计数(读取总数),length
是数字的长度。您甚至可以考虑将其重命名为 numberOfDigits
以更清楚地表明您将创建一个包含该位数的随机数。