【问题标题】:How to determine if three ints are all equal如何确定三个整数是否都相等
【发布时间】:2011-12-28 07:34:51
【问题描述】:

您好,我有三个整数:value1、value2 和 value3。

我如何最好地确定它们是否都相同?

我试过了:

return value1 == value2 == value3

但这是说:

运算符“==”不能应用于“bool”和“int”类型的操作数。

所以我猜它比较前两个返回一个布尔值,它试图与第三个进行比较。

我可以去:

return value1 == value2 && value2 == value3;

但这似乎变得不整洁。

有人有好的建议吗?

【问题讨论】:

  • 大多数语言不支持您的第一种语法(我知道确实支持该语法的唯一语言是 Python)。
  • @NullUserException 你先生有一个正确的名字。干得好。

标签: c#


【解决方案1】:

第二个对我来说还不错。

随着列表变长,这可能会变得笨拙。在这种情况下,我会按照AllSame 编写一个扩展方法。

bool AllSame(this IEnumerable<int> list)
{
    bool first = true;
    int comparand = 0;
    foreach (int i in list) {
       if (first) comparand = i;
       else if (i != comparand) return false;
       first = false;
    }
    return true;
}

或使用params 关键字:

bool AllSame(params int[] list)
{
    return (list as IEnumerable<int>).AllSame();
}

那么你可以写:

if (AllSame(value1, value2, value3, value4, value5)) ...

【讨论】:

  • 我可以相信这被选为正确答案...因为已经有一个 All 扩展方法。
  • @parapurarajkumar, All() 做了一些不同的事情。如果你的意思是list.All(x =&gt; x == list.First()),那么这对于只能迭代一次的集合来说是行不通的。
  • +1 表示第一次失败时退出,真正需要完美的就是 goto。
  • @RitchMelton:不知道你为什么想要一个 goto。我考虑过单独拉出第一次迭代,以避免在每个循环上测试first,但这会更丑陋,尤其是如果你试图保持异常安全。
  • @Ben - 讽刺的真棒。
【解决方案2】:

这对我来说似乎很好。我唯一的评论是你应该为方程引入一个“解释变量”。除了解释计算之外,return 现在为检查结果时提供断点或跟踪点的好地方。

bool allThreeAreEqual = value1 == value2 && value2 == value3;
return allThreeAreEqual;

【讨论】:

    【解决方案3】:

    我修改了我的原始答案以包含一个更通用且不依赖 LINQ 或扩展方法的方法。我认为可以安全地假设这种方法的性能会更高,因为当列表中的早期值不同时,它不必枚举整个列表来确定唯一性。

    class Program 
    { 
        static void Main(string[] args) 
        { 
            int value1 = 1, value2 = 2, value3 = 1; 
            Console.WriteLine(AllAreEqual<int>(value1, value2, value3));
    
            Console.Write("V2: 1 value ");
            Console.WriteLine(AllAreEqual_V2<int>(1));
    
            Console.Write("V2: no value ");
            Console.WriteLine(AllAreEqual_V2<int>());
    
            Console.Write("V2: 3 values, same ");
            Console.WriteLine(AllAreEqual_V2<int>(1, 1, 1));
    
            Console.Write("V2: 3 values, different ");
            Console.WriteLine(AllAreEqual_V2<int>(1, 1, 2));
    
            Console.Write("V2: 2 values, same ");
            Console.WriteLine(AllAreEqual_V2<int>(1, 1));
    
            Console.Write("V2: 2 values, different ");
            Console.WriteLine(AllAreEqual_V2<int>(1, 2));
    
            Console.ReadKey(); 
        } 
    
        static bool AllAreEqual<T>(params T[] args) 
        { 
            return args.Distinct().ToArray().Length == 1; 
        }
    
        static bool AllAreEqual_V2<T>(params T[] args)
        {
            if (args.Length == 0 || args.Length == 1)
            {
                return true;
            }
    
            if (args.Length == 2)
            {
                return args[0].Equals(args[1]);
            }
    
            T first = args[0];
    
            for (int index = 1; index < args.Length; index++)
            {
                if (!first.Equals(args[index]))
                {
                    return false;
                }
            }
    
            return true;
        }
    }
    

    【讨论】:

    • +1; ToArray().Length == 1 可以压缩成Count() == 1
    • O_o.哇。这是通用目的。
    • 感谢 Merlyn,感谢您的改进。
    【解决方案4】:

    如果您只是在寻找优雅(考虑到您已经有一个没有问题的解决方案),您可以使用 good'ol LINQ。这可以处理三个或更多。

    class Program
        {
            static void Main(string[] args)
            {
                List<int> mylist = new List<int>();
                mylist.Add(1);
                mylist.Add(1);
                mylist.Add(1);
                mylist.Add(1);
    
                bool allElementsAreEqual = mylist.All( x => ( x == mylist.First() ));
            }
        }
    

    【讨论】:

    • 我怀疑它会更快返回... All 中没有任何内容需要检查所有元素...
    • 由于某种原因,我连续有两个 thinko。对不起。
    • 如果其中一个不匹配...全部返回false,如果其中两个不匹配则返回false...所以只要所有找到其中一个不满足谓词它不需要对剩余元素评估谓词。你说不是这样吗? MSDN 文档中提到一旦可以确定结果,就会停止源的枚举。
    • 假设你不知道怎么样?显然,其他人有充分的理由投反对票。但你的陪伴很好。我认为有人不喜欢 LINQ 来完成这项任务?
    【解决方案5】:

    你也可以这样做

    bool AllSame(int a, int b, int c, int comparand) {
        return board[a] == comparand && board[b] == comparand && board[c] == comparand;
    }
    

    【讨论】:

      【解决方案6】:
      int nOneInput = 5;
      int nTwoInput = 5;
      int nThreeInput = 5;
      if ((nOneInput + nTwoInput + nThreeInput ) / 3 ==  nOneInput ) 
      {
          // all 3 sides are equal when...
          // the sum of all 3 divided by 3 equals one of the values 
      }
      

      【讨论】:

      • 如果您有 { 5, 4, 6 } 之类的内容,这可能是错误的。平均值仍为 5,但您无法确定所有 3 是否相等。
      【解决方案7】:

      使用 LINQ 对我们来说最好Any()。为什么Any() 而不是All() 是因为All() 将在集合的所有项目上测试谓词,而Any() 将在项目匹配谓词时立即退出。

      这里我使用反向检查。我正在寻找与“a”项目不同的任何项目。因此,一旦它找到一个不同的,我们就知道它们并不完全相等,所以它退出并返回 true。所以它只会测试项目“b”、“c”和“d”。

      // all values to compare
      var a = 4;
      var b = 4;
      var c = 4;
      var d = 8;
      var e = 6;
      var f = 4;
      
      // return if any of the following is different and negate to get a true
      var areSame = (!new[] { b, c, d, e, f}.Any(i => i != a));
      

      如果您覆盖 equals,您可以从中创建可重用的通用扩展,只要它们实现 IEqualityComparer&lt;T&gt;,就可以适用于多种类型

      【讨论】:

      • All() 将在一项不满足谓词时立即退出。
      【解决方案8】:

      这就是我要做的

      if((value1 == value2) && (value1 == value3) && (value2 == value3))
      {
          //Whatever you want here
      }
      

      【讨论】:

      • (value1 == value2) && (value2 == value3) 就够了。
      【解决方案9】:

      接受的答案工作正常,但我也需要支持不同的类型, 所以这是通用版本

            public static bool AllSame<T>(params T[] items)
               {
                  var first = true;
                  T comparand = default;
                  foreach (var i in items)
                  {
                     if (first) comparand = i;
                     else if (!i.Equals(comparand)) return false;
                     first = false;
                  }
                  return true;
               }
      

      用法:

      if (AllSame(true, false, true)) // false
      if (AllSame(5, 5, 5)) // true
      if (AllSame(record1 , record2, record3)) 
      

      【讨论】:

        猜你喜欢
        • 2013-12-30
        • 2022-12-04
        • 1970-01-01
        • 2011-03-26
        • 2016-10-20
        • 1970-01-01
        • 2023-03-31
        • 2016-03-13
        相关资源
        最近更新 更多