Сравнение 5 целых чисел в наименьшем количестве сравнений - PullRequest
2 голосов
/ 21 октября 2009

У меня есть этот код, и мне нужно убедиться, что все переменные результата равны?

long result1 = timer.CalculateElapsedTimeInMinutes();
long result2 = timer.CalculateElapsedTimeInMinutes();
long result3 = timer.CalculateElapsedTimeInMinutes();
long result4 = timer.CalculateElapsedTimeInMinutes();
long result5 = timer.CalculateElapsedTimeInMinutes();

Это то, что я сделал, но я чувствую, что это можно сделать проще, может, нет?

bool allEqual = (result1 == result2) && (result3 == result4) && (result1 == result3) && (result1 == result5);

Спасибо.

Ответы [ 9 ]

14 голосов
/ 21 октября 2009

Это просто о том, что есть какой-то хакерский / хитрый способ сделать это с XOR или чем-то еще - но ваш код ясно дает понять, что вы хотите сделать, и все равно будет невероятно быстрым. Вероятность того, что это станет узким местом, достаточно близка к 0, чтобы не стоить рассматривать ИМО - так что давайте воспользуемся наиболее читаемым кодом.

Я был бы более последовательным в ваших сравнениях:

bool allEqual = (result1 == result2) && 
                (result1 == result3) && 
                (result1 == result4) &&  
                (result1 == result5);

Легче увидеть, что у вас есть все основы, ИМО.

5 голосов
/ 21 октября 2009

Нет, вам понадобится как минимум n -1 сравнений. Хотя я бы написал так:

bool allEqual = (result1 == result2)
             && (result2 == result3)
             && (result3 == result4)
             && (result4 == result5);
2 голосов
/ 21 октября 2009

Вы также можете сделать это с помощью ссылки, используя метод расширения All.

        var results = new long[] {
            timer.CalculateElapsedTimeInMinutes(),
            timer.CalculateElapsedTimeInMinutes(),
            timer.CalculateElapsedTimeInMinutes(),
            timer.CalculateElapsedTimeInMinutes(),
            timer.CalculateElapsedTimeInMinutes()
        };

        bool allEqual = results.All(x => x == results[0]);
2 голосов
/ 21 октября 2009

Нет, это в значительной степени идеально.

Все должно быть сделано максимально просто, но не проще. - Альберт Эйнштейн

1 голос
/ 21 октября 2009

Просто, черт возьми, это сработает?

  bool allequal =
       res1 & res2 & res3 & res4 & res5 == 
       res1 | res2 | res3 | res4 | res5; 

только один сравнение ... <grin> (если не считать побитовые операции!)

1 голос
/ 21 октября 2009

Единственный способ, которым это может быть быстрее, - это замкнуть его таким образом, чтобы пара, наиболее вероятно отличающаяся от него, была оценена первой.

0 голосов
/ 21 октября 2009

Вы также можете сделать вспомогательную функцию для этого:

bool AllEqual<T>(params T[] values) where T : IEquatable<T> {
    // make a decision here and document it
    if (values.Length < 1) return true; // I guess?

    bool result = true;
    T first = values[0];

    for (int i = 1; i < values.Length; i++) {
        result = result && first.Equals(values[i]);
    }

    return result;
}
0 голосов
/ 21 октября 2009

Это зависит от того, что вы подразумеваете под сравнением. Вы можете сделать это, используя только один явный оператор сравнения:

bool result = 
    ((result1 ^ reesult2) | (result1 ^ result3) | (result1 ^ result4) | (result1 ^ result5))==0;

Это может даже иметь преимущество в сгенерированном коде - код, использующий логический код, должен прекратить сравнивать, как только обнаружит любое неравное значение Это означает, что каждое сравнение должно выполняться индивидуально, и оно должно включать код для завершения тестирования после каждого сравнения.

Однако, если вы не делаете это внутри действительно тесного цикла, это того не стоит - просто делайте то, что вы считаете наиболее читабельным.

0 голосов
/ 21 октября 2009

Как насчет этого с LINQ:

var firstValue = timer.CalculateElapsedTimeInMinutes();

var list = new List<long>();
list.Add(timer.CalculateElapsedTimeInMinutes());
list.Add(...);

bool allEqual = list.All(i => i == firstValue);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...