在C#中生成下一个可用的唯一名称

Joa*_*nge 5 .net c# performance

如果您的应用程序中有一个命名系统,其中应用程序包含100个操作,这些操作会创建新对象,例如:

Blur
Sharpen
Contrast
Darken
Matte
...
Run Code Online (Sandbox Code Playgroud)

并在每次使用其中的一个时间,一个新的实例与一个独特的可编辑的名称创建的,像Blur01,Blur02,Blur03,Sharpen01,Matte01,等你将如何产生下一个可用的唯一的名称,所以它是一个O(1)操作或接近恒定时间.请记住,用户还可以将名称更改为自定义名称,例如RemoveFaceDetails等.

有一些约束是可以接受的,例如使用字母,数字,下划线等将字符数限制为100 ......

编辑:您也可以建议解决方案,而不是"填补空白",而不是重复使用已经使用但删除的名称,当然除了自定义的名称.

Mar*_*iec 7

我会在动作类中创建一个静态整数,它会增加并作为每个新类实例的一部分进行分配.例如:

class Blur
{
    private static int count = 0;

    private string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    public Blur()
    {
        _name = "Blur" + count++.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

由于count是静态的,因此每次创建新类时,它都会递增并附加到默认名称.O(1)时间.

编辑

如果您在删除时需要填写漏洞,我建议如下.它会在重命名项目时自动排队,但整体成本会更高:

class Blur
    {
        private static int count = 0;
        private static Queue<int> deletions = new Queue<int>();

        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                Delete();
            }
        }

        private int assigned;

        public Blur()
        {
            if (deletions.Count > 0)
            {
                assigned = deletions.Dequeue();
            }
            else
            {
                assigned = count++;
            }
            _name = "Blur" + assigned.ToString();
        }

        public void Delete()
        {
            if (assigned >= 0)
            {
                deletions.Enqueue(assigned);
                assigned = -1;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

此外,当您删除对象时,您需要在对象上调用.Delete().

CounterClass字典版

class CounterClass
{
   private int count;
   private Queue<int> deletions;

   public CounterClass()
   {
      count = 0;
      deletions = new Queue<int>();
   }

   public string GetNumber()
   {
      if (deletions.Count > 0)
      {
          return deletions.Dequeue().ToString();
      }
      return count++.ToString();
   }

   public void Delete(int num)
   {
      deletions.Enqueue(num);
   }
}
Run Code Online (Sandbox Code Playgroud)

您可以创建一个Dictionary来查找每个字符串的计数器.只要确保解析索引并在重命名或删除值时调用.Delete(int).


Joe*_*ite 7

我推荐你迈克尔A.杰克逊的两个程序优化规则:

  1. 不要这样做.
  2. 仅限专家:不要这样做.

简单,可维护的代码比优化您认为以后可能遇到的速度问题重要得多.

我会开始简单:构建一个候选名称(例如"Sharpen01"),然后遍历现有的过滤器以查看该名称是否存在.如果是,请递增并重试.这是O(N 2),但在获得数千个过滤器之前,这将是足够好的.

如果在某个时候,O(N 2)确实成为一个问题,那么我首先要构建一个现有名称的HashSet.然后,您可以针对HashSet检查每个候选名称,而不是迭代.每次需要唯一名称时重建HashSet,然后扔掉; 你不需要面对变化维护它的复杂性.这将使您的代码易于维护,而只是O(N).

O(N)就足够了.你不需要O(1).用户不会单击"锐化"足够的时间以使其有任何差异.