我在控制台c#代码(7X3'单元')中有一个int数组.我创建它的那一刻,它用零初始化.
我必须将只有五个'细胞'的值改为1,而不改变其他'细胞'的值.我知道这是一个基本的东西,但是,作为C#的绝对新秀,无论我使用什么单元格,我都无法让它工作.你能帮助我吗?
提前致谢.
(注意:因为我经常使用/贡献者,我知道它看起来像经典的"做我的功课"问题而且我道歉,但因为我真的被困在这个weenie部分(我的项目的其余部分都没问题) ,我很感激帮助).
以下是解决这个问题的两种方法,第一种方法; 调用BruteForceRandomImplementation很容易实现和理解,但是一旦你试图用1来标记大量的位置,由于它的强制使用Random直到它填充足够的位置,所以很慢.
/// <summary>
/// This method uses a random based algorithm to create a two-dimensional array of [height, width]
/// with exactly locationsToFind locations set to 1.
/// </summary>
/// <param name="height"></param>
/// <param name="width"></param>
/// <param name="locationsToFind"></param>
/// <returns></returns>
public int[,] BruteForceRandomImplementation(int height, int width, int locationsToFind)
{
var random = new Random();
locationsToFind = LimitLocationsToFindToMaxLocations(height, width, locationsToFind);
// Create our two-dimensional array.
var map = new int[height, width];
int locationsFound = 0;
// Randomly set positons to 1 untill we have set locationsToFind locations to 1.
while (locationsFound < locationsToFind)
{
// Get a random Y location - limit the max value to our height - 1.
var randomY = random.Next(height);
// Get a random X location - limit the max value to our width - 1.
var randomX = random.Next(width);
// Find another random location if this location is already set to 1.
if (map[randomY, randomX] == 1)
continue;
// Otherwise set our location to 1 and increment the number of locations we've found.
map[randomY, randomX] = 1;
locationsFound += 1;
}
return map;
}
Run Code Online (Sandbox Code Playgroud)
使用以下辅助方法来保持我们的locationsToFind范围合理:
/// <summary>
/// Limits the locationsToFind variable to the maximum available locations. This avoids attempting to
/// mark more locations than are available for our width and height.
/// </summary>
/// <param name="height"></param>
/// <param name="width"></param>
/// <param name="locationsToFind"></param>
/// <returns></returns>
public int LimitLocationsToFindToMaxLocations(int height, int width, int locationsToFind)
{
return Math.Min(locationsToFind, height * width);
}
Run Code Online (Sandbox Code Playgroud)
我所谓的第二实施ShuffleImplementation是一个很大更快当你标记大量的独特位置.它创建了一个一维数组,用足够的1来填充它以满足您的需求然后使用Fisher-Yates shuffle对该数组进行洗牌,最后将这个一维数组扩展为二维数组:
/// <summary>
/// This method uses a shuffle based algorithm to create a two-dimensional array of [height, width]
/// with exactly locationsToFind locations set to 1.
/// </summary>
/// <param name="height"></param>
/// <param name="width"></param>
/// <param name="locationsToFind"></param>
/// <returns></returns>
public int[,] ShuffleImplementation(int height, int width, int locationsToFind)
{
locationsToFind = LimitLocationsToFindToMaxLocations(height, width, locationsToFind);
// Create a 1 dimensional array large enough to contain all our values.
var array = new int[height * width];
// Set locationToFind locations to 1.
for (int location = 0; location < locationsToFind; location++)
array[location] = 1;
// Shuffle our array.
Shuffle(array);
// Now let's create our two-dimensional array.
var map = new int[height, width];
int index = 0;
// Expand our one-dimensional array into a two-dimensional one.
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
map[y, x] = array[index];
index++;
}
}
return map;
}
/// <summary>
/// Shuffles a one-dimensional array using the Fisher-Yates shuffle.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="arr"></param>
public static void Shuffle<T>(T[] array)
{
var random = new Random();
for (int i = array.Length - 1; i > 0; i--)
{
int n = random.Next(i + 1);
Swap(ref array[i], ref array[n]);
}
}
/// <summary>
/// Swaps two values around.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="valueA"></param>
/// <param name="valueB"></param>
public static void Swap<T>(ref T valueA, ref T valueB)
{
T tempValue = valueA;
valueA = valueB;
valueB = tempValue;
}
Run Code Online (Sandbox Code Playgroud)
用法:
var map = BruteForceRandomImplementation(7, 3, 5);
Run Code Online (Sandbox Code Playgroud)
要么:
var map = ShuffleImplementation(7, 3, 5);
Run Code Online (Sandbox Code Playgroud)
取决于您要使用的是哪一个.有关两者之间性能差异的一个很好的例子,请尝试:
int width = 1000;
int height = 1000;
int locationsToFind = (width * height) - 1;
var stopwatch = new Stopwatch();
stopwatch.Start();
BruteForceRandomImplementation(height, width, locationsToFind);
stopwatch.Stop();
Console.WriteLine(string.Format("BruteForceRandomImplementation took {0}ms", stopwatch.ElapsedMilliseconds));
stopwatch.Restart();
ShuffleImplementation(height, width, locationsToFind);
stopwatch.Stop();
Console.WriteLine(string.Format("ShuffleImplementation took {0}ms", stopwatch.ElapsedMilliseconds));
Run Code Online (Sandbox Code Playgroud)
在我的笔记本电脑上,BruteForceRandomImplementation耗时1205ms,ShuffleImplementation耗时67ms或接近18倍.