Определить что элементы одной коллекции являются квадратными корнями другой
Подскажите можно-ли написать более оптимальный алгоритм. Задача звучит так:
Нужно проверить что все в коллекции numbers являются квадратными корнями чисел в коллекции squares. Коллекции отсортированы по возрастанию и не имеют отрицательных значений.
update: если коллекции разной длины то считаем это как false
Примеры входных данных и ответы:
IN: {1, 2}, {1, 4} OUT: TRUEIN: {1, 3, 5}, {1, 9, 25, 25} OUT: FALSE
Сигнатура функции:
bool TestForSquares(IEnumerable<int> numbers, IEnumerable<int> squares)
Моё решение:
public static bool TestForSquares(IEnumerable<int> numbers, IEnumerable<int> squares) {
var isFirstIteration = true;
var numbersEnumerator = numbers.GetEnumerator();
var squaresEnumerator = squares.GetEnumerator();
while (true) {
bool numberHasNext = numbersEnumerator.MoveNext();
bool squareHasNext = squaresEnumerator.MoveNext();
if(numberHasNext != squareHasNext) {
// случай когда две коллекции имеют разный размер
return false;
}
if(!numberHasNext && !squareHasNext) {
if (isFirstIteration) {
// случай когда две коллекции пусты
return false;
}
break;
}
var testData = numbersEnumerator.Current * numbersEnumerator.Current;
if(testData != squaresEnumerator.Current) {
return false;
}
isFirstIteration = false;
}
return true;
}
p.s.
Так же интересует решение с той же оптимальностью но не такое многословное.
Ответы (2 шт):
Может быть можно возвести в квадрат все элементы одного списка, а затем проверить, содержит ли один список все элементы второго, используя метод Intersect: https://stackoverflow.com/questions/3274541/check-if-one-ienumerable-contains-all-elements-of-another-ienumerable ?
В C# сейчас есть аналог питоновского Zip, так что можно коротко и просто проверять примерно так:
coll1.Zip(coll2).All(x => x.First * x.First == x.Second)
Но проверку на совпадение длины коллекций надо делать дополнительно. А вот делать эту проверку до или после сравнения элементов коллекций - это зависит от природы коллекций. Если это готовые массивы или там списки, то можно проверить длину заранее, так будет быстрее всего работать. А если это потоковые данные, и особенно если их вообще нельзя перебирать второй раз, то тут решение с Zip вообще не подойдёт, наверное.