【问题标题】:inserting element into a list, if condition is met with C#如果 C# 满足条件,则将元素插入列表
【发布时间】:2012-04-10 18:24:45
【问题描述】:

如果没有这样的数字,如何在列表中间插入一些数字?

在下面的示例中,我尝试插入数字 4

        List<int> list1 = new List<int>(){ 0, 1, 2, 3, 5, 6 };
        int must_enter = 4;
        if (!list1.Contains(must_enter))
        {
            list1.Add(must_enter);
        }

因为结果编号将在列表末尾输入,但我希望它在 3 之后(5 之前)。

请注意,由于项目的具体情况,我不能使用排序列表,但列表中的所有数字保证按升序排列 (0,2,6,9,10,. ..)

编辑:我知道一个错误,这就是我所做的:

        List<int> list0 = new List<int>() { 1, 2, 3, 5, 6 };
        int must_enter = 7;
        if (!list0.Contains(must_enter))
        {
            if (must_enter < list0.Max())
            {
                int result = list0.FindIndex(item => item > must_enter || must_enter > list0.Max());
                list0.Insert(result, must_enter);
            }
            else
            {
                list0.Add(must_enter);
            }

        }

edit2:无论如何,由于几个因素,我已经切换到 BinarySearch 方法。大家感谢您的帮助!

【问题讨论】:

  • 你接受了错误的解决方案检查@EsotericScreenName 答案后的评论.....它给你一个错误......
  • @PranayRana 查看编辑.. 感谢您的关注
  • 只是为了注意接受的答案仍然没有回答你需要什么它只是搜索和插入它不是为每个缺少的元素循环......所以你需要根据那个修改你的代码.....

标签: c# list


【解决方案1】:

你可以这样做:

int index = list1.BinarySearch(must_enter);
if (index < 0)
 list1.Insert(~index, must_enter);

这样,您将保持列表以最佳性能排序。

【讨论】:

  • 尽管以前的方法对我来说效果很好,但我必须承认您的解决方案快速且非常简单......绝对是最好的答案
  • -1 - 只是要注意答案仍然没有回答 OP 需要什么,它只是搜索和插入它,而不是为每个丢失的元素循环...... .所以你需要根据那个修改你的代码.....像{0,2,6,9,10}这样的列表需要在其中插入1,3,4,5
  • 不,没关系,我不需要知道缺少什么。如有必要,我只需要查找并插入一个数字,除此之外的所有其他数字都是无关紧要的,所以答案完全回答了我的问题。如果有什么误解,请见谅
  • @Alex - 如果你只需要这样的方法就是 Inset 方法,别无其他.....
  • @Casperah 似乎毫无理由地否决了 3 个答案。因此,以充分的理由投票和评论是一种很好的做法。他似乎想突出他的答案。是的,这是一个很好的答案,但仍然不明白他为什么会这样。
【解决方案2】:

你可以这样做:

list1.Add(must_enter);

然后对列表进行排序:

list1 = list1.OrderBy(n => n).ToList();

结果将是:

0, 1, 2, 3, 4, 5, 6 

编辑:

或者使用扩展方法:

static class Utility
{
     public static void InsertElement(this List<int> list, int n)
     {
         if(!list.Contains(n))
         {     
             for(int i = 0; i < list.Count; i++)
             {
                  if(list[i] > n)
                  {
                     list.Insert(i-1, n);
                     break;
                  }

                  if(i == list.Count - 1)
                     list.Add(n);
             }
         }
     }
}

然后:

list1.InsertElement(must_enter);

【讨论】:

  • 我认为 OP 的 project's specifics 不允许这样做 :)
  • 我认为 list1.Sort() 会更快地完成这项工作,但它仍然缺乏性能。
  • 他不想使用排序列表。
  • +1 - 大多数人都投了反对票,这样他们的答案就会得到更多的关注,所以不用担心你的答案符合要求
  • 谢谢...感谢您在这里解决它已经很混乱的问题,我现在就留下这个问题
【解决方案3】:

你正在寻找

list1.Insert(index, must_enter);

在特定索引处插入元素,而不是在列表末尾。

您必须首先找到要插入的索引,这可以通过二分搜索轻松完成。从列表中间的值开始,并将其与要插入的数字进行比较。如果更大,则搜索列表的下半部分,如果更大,则搜索列表的上半部分。重复该过程,每次将列表分成两半,直到找到之前的项目小于您插入的项目并且之后的项目大于您插入的项目的位置。 (编辑:当然,如果您的列表总是很小,那么从头开始遍历列表以找到正确的位置可能会更轻松!)

【讨论】:

    【解决方案4】:
    List<int> list1 = new List<int>() { 0, 1, 2, 3, 5, 6 };
    int must_enter = 4;
    
    for (int i = 0; i < list1.Count; i++)
    {
         if (must_enter >= list1[i])
         {
             list1.Insert(i + 1, must_enter);
         }
    }
    

    编辑:我喜欢 sarwar026,实现更好。

    【讨论】:

      【解决方案5】:
      list1.Insert(4, 4)
      

      List&lt;T&gt;.Insert Method - 将一个元素插入到列表中指定索引处。

      快速笔记- List 类型上的 Insert 实例方法在很多情况下性能并不好。因为对于Insert,list需要调整以下元素。

      这是我得到这个答案的原始帖子尝试一下可能会对你有所帮助:Finding best position for element in list

      List<int> list = new List<int>{0,2,6,9,10};
      for (int i = 0; i < list1.Count; i++)
      {
         int index = list.BinarySearch(i);
         if( i < 0)
         {
          int insertIndex = ~index; 
          list.Insert(insertIndex, i);
         }
      }
      

      仅针对操作需要的一个缺失元素

         int index = list.BinarySearch(4);
         if( index < 0)
         {
          int insertIndex = ~index; 
          list.Insert(insertIndex, 4);
         }
      

      或

      List<int> list1 = new List<int>() { 0,2,6,9,10 };
      int must_enter = 4;
      
      for (int i = 0; i < list1.Count; i++)
      {
           if (!list1.Contains(i))
           {
               list1.Insert(i , i);
           }
      }
      

      仅针对操作需要的一个元素

           if (!list1.Contains(4))
           {
               list1.Insert(4 , 4);
           }
      

      【讨论】:

      • 对于列表(0,2,6,9,10,...) ?
      • @Casperah - 它并不完全不正确......因为他发布了这样的问题,我建议使用插入方法而不是添加其他东西,因为他添加了一些清晰的想法......我希望你喜欢考虑这一点并删除您的反对意见
      • @Casperah - 检查我的更新,我为此提出了二进制搜索的解决方案,而不是插入元素,我希望它不正确
      • @sarwar026 - 我编辑了我的答案,添加了用于插入元素的二进制搜索希望您对此感兴趣并可能会删除您的反对意见
      • @Pranay +1 修复某些人的反对票,但不仅是,不错的答案:)
      【解决方案6】:
          List<int> list1 = new List<int>(){ 0, 1, 2, 3, 5, 6 };
          int must_enter = 4;
          if (!list1.Contains(must_enter))
          {
              int result = list.FindIndex(item => item > must_enter);
              if(result!=-1)
                  list1.Insert(result, must_enter);
              else  // must_enter is not found
              {
                  if(must_enter > list.Max()) // must_enter > max value of list
                      list1.Add(must_enter);
                  else if(must_enter < list.Min())  // must_enter < min value of list
                      list1.Insert(0, must_enter);
              }
          }
      

      首先,找到大于must_enter(4)的数字的索引,然后将must_enter插入该位置

      【讨论】:

      • 我认为它存在严重的性能问题。循环整个集合两次以添加一个整数。 O(2*n)
      • -1:在您的示例中,如果must_enter > 6,您的代码将引发异常,因为FindIndex 返回-1。
      • @EsotericScreenName:谢谢。我已经更新了我的代码。希望它现在可以完美运行。
      • @sarwar026:代码仍然损坏。在 else 块中,您已经切换了大于/小于符号,并且您仍在尝试在索引 -1 处插入记录。
      • @Casperah:插入到列表中间的已经是O(N),这也不错。
      【解决方案7】:
      if (!list1.Contains(must_enter))
      {
          SortedSet<int> sorted = new SortedSet<int>( list1 );
          sorted.Add( must_enter );
          list1 = sorted.ToList();
      }
      

      【讨论】:

      • 循环遍历整个集合,再次对其进行排序并添加新值,然后将其转换回列表。我认为这不是完成这项简单任务的最佳方式。
      • @Casperah。我很好奇,所以我将我的解决方案与您的解决方案进行了对比。事实证明,您的解决方案大约快 200%。
      • 太好了,我喜欢你实际测试过的事实,我会通过撤销我的反对票来回报你。
      猜你喜欢
      • 2019-03-01
      • 2023-04-05
      • 2020-01-22
      • 2011-03-19
      • 2013-11-15
      • 2015-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多