C# 搜索整数数组中的重复项
我目前正在用C#创建一个非常基本的游戏,我创建了一个库存系统,使用一个非常简单的命令(Items.Add(id,amount))可以将物品添加到所述库存中。我希望能够做到的是,我当前的系统没有做到的是能够有效地“搜索”我的库存数组,它是一个包含项目id和项目金额的2D数组。我目前的系统是这样的:C# 搜索整数数组中的重复项,c#,arrays,C#,Arrays,我目前正在用C#创建一个非常基本的游戏,我创建了一个库存系统,使用一个非常简单的命令(Items.Add(id,amount))可以将物品添加到所述库存中。我希望能够做到的是,我当前的系统没有做到的是能够有效地“搜索”我的库存数组,它是一个包含项目id和项目金额的2D数组。我目前的系统是这样的: public static void add(int id, int amount) { for (int i = 0; i < Ship_Builder.Player.invCount;
public static void add(int id, int amount)
{
for (int i = 0; i < Ship_Builder.Player.invCount; i++)
{
if (Ship_Builder.Player.inv[i, 0] == 0)
{
Ship_Builder.Player.inv[i, 0] = id;
Ship_Builder.Player.inv[i, 1] = amount;
}
}
Ship_Builder.Player.invCount++;
}
public class InventoryItem
{
public int Id { get; set; }
public int Amount { get; set; }
// Now I can add other useful properties here too
// ...like Name perhaps?
}
public void Add(int id, int amount)
{
// assuming myInventory is our inventory
if (myInventory.ContainsKey(id)) {
myInventory[id].Amount += amount;
}
else {
myInventory[id] = new InventoryItem()
{
Id = id,
Amount = amount
};
}
}
以前,但它没有按照我的要求工作。
任何帮助都将不胜感激,谢谢,
Laurence.这里有很多事情要做(没有足够的细节来给出任何答案,除了大致的笔划),但我将如何处理类似的事情,将从使用面向对象的设计开始,而不是依赖数组中的索引位置。我会这样定义:
public static void add(int id, int amount)
{
for (int i = 0; i < Ship_Builder.Player.invCount; i++)
{
if (Ship_Builder.Player.inv[i, 0] == 0)
{
Ship_Builder.Player.inv[i, 0] = id;
Ship_Builder.Player.inv[i, 1] = amount;
}
}
Ship_Builder.Player.invCount++;
}
public class InventoryItem
{
public int Id { get; set; }
public int Amount { get; set; }
// Now I can add other useful properties here too
// ...like Name perhaps?
}
public void Add(int id, int amount)
{
// assuming myInventory is our inventory
if (myInventory.ContainsKey(id)) {
myInventory[id].Amount += amount;
}
else {
myInventory[id] = new InventoryItem()
{
Id = id,
Amount = amount
};
}
}
现在,我将我的清单设置为一个字典
,并向清单中添加一些内容可能如下所示:
public static void add(int id, int amount)
{
for (int i = 0; i < Ship_Builder.Player.invCount; i++)
{
if (Ship_Builder.Player.inv[i, 0] == 0)
{
Ship_Builder.Player.inv[i, 0] = id;
Ship_Builder.Player.inv[i, 1] = amount;
}
}
Ship_Builder.Player.invCount++;
}
public class InventoryItem
{
public int Id { get; set; }
public int Amount { get; set; }
// Now I can add other useful properties here too
// ...like Name perhaps?
}
public void Add(int id, int amount)
{
// assuming myInventory is our inventory
if (myInventory.ContainsKey(id)) {
myInventory[id].Amount += amount;
}
else {
myInventory[id] = new InventoryItem()
{
Id = id,
Amount = amount
};
}
}
现在,您不必实际使用InventoryItem
类,您可以继续使用dictional
,但您可能会发现,在使用它的过程中,您更希望使用一些对象
然后,您可能有一个包含所有对象的主词典,只需将它们添加到您的库存中,就可以得到如下结果:
public void Add(InventoryItem item, int amount)
{
// assuming myInventory is our inventory
if (myInventory.ContainsKey(item.Id)) {
myInventory[item.Id].Amount += amount;
}
else {
myInventory[item.Id] = new InventoryItem(item) // assuming you added a
// copy constructor, for example
{
Amount = amount
};
}
}
正如评论所建议的那样,您应该使用
字典来完成这样的任务。但是,如果你必须使用一个二维数组,在我们添加任何项之前,它(我假设)预先填充了零,那么像你建议的if-else
语句就不会起作用。您需要做的是首先遍历数组寻找匹配的id
,每次id
不匹配时,您必须检查当前正在检查的id
是否等于0。如果是,那么您已经遍历了所有“插槽”,其中包含一些项目,但没有找到匹配项,这意味着该项目必须进入另一个空插槽
public static void add(int id, int amount)
{
for (int i = 0; i < Ship_Builder.Player.invCount; i++)
{
if (Ship_Builder.Player.inv[i, 0] != id)
{
if (Ship_Builder.Player.inv[i, 0] == 0)
{
Ship_Builder.Player.inv[i, 0] = id;
Ship_Builder.Player.inv[i, 1] = amount;
Ship_Builder.Player.invCount++;
continue;
}
}
else
{
Ship_Builder.Player.inv[i, 1] += amount;
continue;
}
}
}
publicstaticvoidadd(整数id,整数金额)
{
对于(int i=0;i
警告我的答案假设您在具有最小索引的空插槽中找到新项目。此外,如果要删除项并将id
设置为零,则必须首先遍历整个数组以搜索匹配索引,然后才能分配新项。如果阵列很大,这在时间上可能会非常昂贵。根据速度性能要求(使用阵列的速度应略高于此要求),您可以将硬编码值和阵列一起跳过。这有几个半高级主题:
public abstract class InventoryItem
// or interface
{
public abstract string Name { get; }
public int Count { get; set; }
}
public class InventoryGold : InventoryItem
{
public string Name { get { return "Gold" } }
}
public abstract class InventoryWeapon : InventoryItem { }
public class OgreSlayingKnife : InventoryWeapon
{
public string Name { get { return "Ogre Slaying Knife"; } }
public int VersusOgres { get { return +9; } }
}
public UpdateCount<Item>(this ICollection<Item> instance,
int absoluteCount)
{
var item = instance.OfType<Item>().FirstOrDefault();
if (item == null && absoluteCount > 0)
{
item = default(Item);
item.Count = absoluteCount;
instance.add(item);
}
else
{
if (absoluteCount > 0)
item.Count = absoluteCount;
else
instance.Remove(item);
}
}
// Probably should be a Hashset
var inventory = new List<InventoryItem>();
inventory.UpdateCount<InventoryGold>(10);
inventory.UpdateCount<OgreSlayingKnife(1)
公共抽象类InventoryItem
//或接口
{
公共抽象字符串名称{get;}
公共整数计数{get;set;}
}
公共类InventoryGold:InventoryItem
{
公共字符串名称{get{return“Gold”}
}
公共抽象类inventoryWearm:InventoryItem{}
公共级奥格雷斯莱因刀:库存武器
{
公共字符串名称{获取{返回“食人魔屠刀”;}
public int VersusOgres{get{return+9;}}
}
public UpdateCount(此ICollection实例,
整数(绝对计数)
{
var item=instance.OfType().FirstOrDefault();
如果(项==null&&absoluteCount>0)
{
项目=默认(项目);
项目计数=绝对计数;
实例.添加(项);
}
其他的
{
如果(绝对计数>0)
项目计数=绝对计数;
其他的
实例。删除(项目);
}
}
//可能应该是一个哈希集
var inventory=新列表();
存货。更新账户(10);
inventory.UpdateCount为什么使用数组,为什么不使用字典?在搜索这个问题的答案之前,我还没有研究过字典,我真的不想重新编写我的所有子系统(依赖于数组中的库存)是如何工作的……我真的不理解您的“搜索”功能。你能提供一些输入/输出示例吗?@LaurieWalpole:老实说,使用字典不需要太多重构,而且字典可能比你要做的查找要快得多。只需将其设置为字典,而不是尝试使用锯齿状数组,您可以执行inv[0]=1
您真的应该接受@ErikPhilips的建议并使用字典。2D数组在.NET中不是最容易使用的(锯齿状数组或列表更容易使用),使用字典会使查找速度更快。感谢您提供了令人惊讶的答案,我以后可能会改用字典,但现在我将坚持使用当前系统。我唯一要更改的是枚举的ID。如果说myInventory[Inventory.Gold]
等,将使代码读/写更加简单。非常感谢您的回答,它返回了一个超出范围的异常,但我现在正在计算-数组的最大长度为50,所以应该可以。