请使用C#将一个长度为100的 int 数组,插入1-100的随机数,不能重复,要求遍历次数最少。
逐句思考:
首先,想要产生100个随机数
可以使用 for 循环
List<int> list = new List<int>();
for (int i = 0; i < 100; i++)
{
int num = r.Next(1, 101);
list.Add(num);
}
这样,数组中就有了100个随机数。
但是,这100个随机数是包含重复值的,所以,方法不适用。
其次,不能重复。
那就拒绝已添加的数值再次加入。
设定一个判断
if (!list.Contains(num))
{
list.Add(num);
}
这样,可以确保数组内的数值都是唯一的,但是数组元素个数将不足100。
最后,遍历次数最少
没有最好,只有更好——算法优化。
回归正题:
方法一:
var r = new Random();
List<int> list = new List<int>();
int count = 0;
while (list.Count < 100)
{
int num = r.Next(1, 101);
if (!list.Contains(num))
{
list.Add(num);
}
count++;
}
foreach (var i in list)
{
Console.Write(i + "\t");
}
Console.WriteLine("一共遍历了{0}次", count);
方法二:
使用 HashSet
HashSet存放元素过程:
将一个元素存入HashSet中时,HashSet会先调用对象的hashCode方法,以此确定对象的存储位置,之后HashSet会查询对应的hashCode位置是否已经存储对象
{
如果存储了,则会调用equals方法判断两个对象是否相同:
{
如果相同:
{
则不存储。
}
如果不同:
{
则在相同的hashCode位置使用链表的形式存储进去,但会影响HashSet性能。
}
}
如果没有存储:
{
则直接存储进去。
}
}
与方法一差别不大,只是少了一个 if 判断。
var r = new Random();
HashSet<int> h = new HashSet<int>();
int count = 0;
while (h.Count < 100)
{
h.Add(r.Next(1, 101));
count++;
}
foreach (var i in h)
{
Console.Write(i + "\t");
}
Console.WriteLine("一共遍历了{0}次", count);
方法三:
List<int> list1 = new List<int>(), list2 = new List<int>();
var count = 0;
for (int i = 1; i < 101; i++)
{
list1.Add(i);
count++;
}
var r = new Random();
while (list2.Count < 100)
{
var index = r.Next(0, list1.Count);
list2.Add(list1[index]);
list1.RemoveAt(index);
count++;
}
foreach (var i in list2)
{
Console.Write(i + "\t");
}
Console.WriteLine("一共遍历了{0}次", count);
此方案一共遍历200次,初始化遍历100次,重新赋值再遍历100次,并且数字是随机不重复的。
每遍历一次,list1就会删除一个元素,即使产生的随机数据相同,但每次对于list1的索引对应的值是不同的,能保证数字唯一性。
附:完整代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace project_Test
{
class Program
{
static void Main(string[] args)
{
Test.Method1();
Test.Method2();
Test.Method3();
}
}
class Test
{
public static void Method1()
{
var r = new Random();
List<int> list = new List<int>();
int count = 0;
while (list.Count < 100)
{
int num = r.Next(1, 101);
if (!list.Contains(num))
{
list.Add(num);
}
count++;
}
foreach (var i in list)
{
Console.Write(i + "\t");
}
Console.WriteLine("一共遍历了{0}次", count);
}
public static void Method2()
{
var r = new Random();
HashSet<int> h = new HashSet<int>();
int count = 0;
while (h.Count < 100)
{
h.Add(r.Next(1, 101));
count++;
}
foreach (var i in h)
{
Console.Write(i + "\t");
}
Console.WriteLine("一共遍历了{0}次", count);
}
public static void Method3()
{
List<int> list1 = new List<int>(), list2 = new List<int>();
var count = 0;
for (int i = 1; i < 101; i++)
{
list1.Add(i);
count++;
}
var r = new Random();
while (list2.Count < 100)
{
var index = r.Next(0, list1.Count);
list2.Add(list1[index]);
list1.RemoveAt(index);
count++;
}
foreach (var i in list2)
{
Console.Write(i + "\t");
}
Console.WriteLine("一共遍历了{0}次", count);
}
}
}
over.