在整数数组中搜索重复项

本文关键字:搜索 整数 数组 | 更新日期: 2023-09-27 18:15:01

我目前正在用c#创建一个非常基本的游戏,我有一个使用非常简单的命令(物品)创建的库存系统。添加(id, amount)),你可以添加物品到该库存。我希望能够有效地"搜索"我的库存数组,这是一个包含道具id和道具数量的2D数组,这是我目前的系统所不能做到的。我现在的系统是这样的:

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++;
}

,我希望它(在else if中)能够搜索数组。我确实有这个:

else if (Ship_Builder.Player.inv[i, 0] == Ship_Builder.Player.inv[i + 1, 0])
{
    //Do
}

以前,但它不像我想的那样工作。任何帮助都将非常感激,谢谢。劳伦斯。

在整数数组中搜索重复项

正如注释所建议的,您应该使用Dictionary来完成这样的任务。但是,如果您必须使用二维数组,(我假设)在我们向其添加任何项目之前预先填充了零,那么像您建议的if-else语句将不起作用。你需要做的是先遍历数组寻找匹配的id,每次你的id s不匹配,你必须检查你当前检查的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;
        }
    }
}

警告!我的答案假设您在空槽中找到具有最小索引的新项。此外,如果您要删除项并将id设置为零,那么您必须首先遍历整个数组以搜索匹配的索引,然后才能分配新项。如果数组很大,这可能会非常耗费时间。

这里有很多事情要做(并且没有足够的细节来给出任何答案,除了粗略的描述),但是我如何处理这样的事情将从使用对象面向设计开始,而不是依赖于数组中的索引位置。我将这样定义:

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?
}

现在我将我的库存设置为Dictionary<int,InventoryItem>,并添加一些东西到我的库存中,可能看起来像这样:

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类,你可以只坚持使用Dictonary<int,int>,但你可能会发现,当你通过它,你更愿意有一些对象来工作。

那么你可能会有一个所有对象的主字典,然后把它们添加到你的库存中,所以你最终会得到这样的东西:

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
        };
    }
}

根据速度性能要求(使用数组应该只比这稍微快一点),您可以直接跳过硬编码值和数组。这里有几个半高级的主题:

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)