请原谅我的愚蠢我不认为我的咖啡已经踢了:(
我正在尝试遍历两个列表,并根据两个列表的值创建一个赋值。 例如。 列表1是我要创建的文件夹列表 清单2是具有可用空间的硬盘驱动器列表
我希望通过列表计数在驱动器上传播文件夹创建不相等。
所以我想让对于文件夹列表中的第一次迭代尝试驱动器1,如果它有空间并且还没有文件夹创建它。 然后移动到文件夹2并驱动两个 - 然后驱动器三和驱动器三(如果驱动器的总数是3)我想移回驱动一个用于下一个文件夹,直到创建所有文件夹。
任何人都可以帮我提供如何到达那里的样本吗?
答案 0 :(得分:2)
我经常考虑的问题是"我怎样才能将棘手的机制转移到他们自己的类型上?#34;。在你的情况下,你想要一个列表的枚举,它在完成时重新开始,但另一种思考方式是让一个计数器在到达范围顶部时回绕。所以,让我们实现:
struct WrappingCounter
{
private int current;
private int max;
public WrappingCounter(int max) : this(0, max) {
if (max <= 0) throw new ArgumentException();
}
private WrappingCounter(int current, int max)
{
this.current = current % max;
this.max = max;
}
public static implicit operator int(WrappingCounter c) {
return c.current;
}
public static WrappingCounter operator ++(WrappingCounter c) {
return new WrappingCounter(c.current + 1, c.max);
}
}
这段代码也很有趣,因为它是如何在C#中编写正确的++
运算符的对象课程。请注意++
返回递增值,与C ++不同。它不会改变c
;它会生成一个 new 对象,表示递增的c
。编译器将在适当的时候进行分配。
现在我们已经将丑陋的机制分离到了他们自己的类型,现在主要的算法变得更容易阅读:
var dirs = new List<string> { "dir1", "dir2", "dir3" };
var drives = new List<string> { "drive1", "drive2" };
var c = new WrappingCounter(drives.Count);
foreach(var dir in dirs) {
var drive = drives[c];
c++;
Console.WriteLine(dir + " " + drive);
}
答案 1 :(得分:0)
以下是算法的概要。它将第一个文件夹与第一个驱动器匹配,第二个文件夹与第二个驱动器匹配,依此类推。除非没有足够的空间。然后它将尝试后续驱动器(在循环中)。一旦找到空间,它将在找到最后一个之后继续在驱动器上进行迭代。例如:
folder_1 - &gt; drive_a
folder_2 - &gt; drive_b
folder_3 - &gt; (skip drive_c) - &gt; drive_d
folder_4 - &gt; drive_e
等
// You'll need to associate required space with each folder
public class FolderThing
{
public string Name {get; set;}
public int Size {get; set;}
}
// Each drive will need to track available free space
public class DriveThing
{
public string Name {get; set;}
public int AvailableSpace {get; set;}
}
// Collection of folders, populate as required.
var foldersToAllocate = new List<FolderThing>();
// Collection of drives, populate as required.
var drivesToUse = new List<DriveThing>();
var numberOfDrives = drivesToUse.Count();
int nextDrive = 0;
foreach (var f in foldersToAllocate)
{
// Track whether space could be allocated ...
bool spaceFound = false;
int tryCount = 0;
// For loop, to exit early on success.
// Try every available drive once, until space is found.
for (tryCount=0; tryCount<numberOfDrives; tryCount++)
{
var drive = drivesToUse[(tryCount + nextDrive) % numberOfDrives];
if (drive.AvailableSpace > f.Size)
{
// do the allocate thing
// update space used for drive
spaceFound = true;
break;
}
}
// Increment to the next drive after the previous one.
nextDrive = (nextDrive + tryCount + 1) % numberOfDrives;
if (spaceFound == false)
{
throw new Exception("Could not find enough free space");
}
}