C как сравнить элементы массива

от admin

Сравнение двух массивов в C, поэлементно

Я ломал голову над достижением чего-то очень простого на C, чтобы сделать мою одну из программ (написанную не мной) в нашем проекте вычислительной физики более динамичной: сравнение двух разных массивов элемент за элементом в условном if.

Каждый раз, когда мы запускаем нашу программу, массив a[ ] содержит различное количество значимых элементов; например, прямо сейчас мы используем эту подпрограмму только для элементов с [1] по [4] . Однако в других случаях мы захотим иметь меньше или больше элементов, скажем, до 3 элементов или до 5 элементов соответственно.

По сути, я хочу иметь возможность переписать приведенный выше оператор if, чтобы он был динамическим . другими словами, если рассматривается N элементов, то он будет работать :

Таким образом, это if должно меняться всякий раз, когда изменяется количество интересующих нас элементов N (N определяется как #define в заголовке этого файла, который я только что назвал header.h).

Буду очень признателен за вашу поддержку в этой задаче. Спасибо.

6 ответов

Лучше всего переписать его как функцию, возвращающую истину или ложь (1 или 0):

Обратите внимание, что обычно сравнивать двойники на равенство — плохая практика — лучше сравнить их разницу и убедиться, что абсолютное значение меньше некоторого допуска.

Также обратите внимание, что вы сравниваете элементы с 1 по n — массивы C начинаются с 0.

Вы бы использовали вышеуказанное с

Где значение N равно #define ‘d на ваш вопрос.

Если вы хотите быть «умным» и избежать цикла, вы можете написать следующее — он остановится («закоротит»), как только вы достигнете нужного количества сравнений. все еще Плохая идея сравнивать двойники на равенство, но я оставлю это на другой раз (см. Комментарий в коде выше для решения).

Это делает «и остальное» true , как только вы сравните нужное количество терминов, поэтому он перестанет оценивать термины (по мере необходимости). Я не уверен, что это быстрее или лучше код, но он «динамический» . Очевидно, вы можете создавать это выражение сколько угодно долго; Я просто написал первые три условия, чтобы вы поняли. Я ЭТО НЕ РЕКОМЕНДУЮ.

Что касается сравнения двойников, вы можете подумать о замене

Где вы определяете макрос

Это гарантирует, что ваши двойники не обязательно должны быть «точно равными» — в зависимости от того, как вы к ним пришли, их почти никогда не будет, а относительного допуска 1 часть из 10 ^ 10 обычно достаточно для большинства практических сравнений. .

Comparing arrays in C#

I am trying to compare two arrays with each other. I tried this code and got the following errors.

Why do I get that error? I went for a low-tech solution and did this which works fine, but I need to copy/paste it several times for each type.

6 Answers 6

Providing that you have LINQ available and don’t care too much about performance, the easiest thing is the following:

In fact, it’s probably worth checking with Reflector or ILSpy what the SequenceEqual methods actually does, since it may well optimise for the special case of array values anyway!

«Why do i get that error?» — probably, you don’t have » using System.Collections; » at the top of the file — only » using System.Collections.Generic; » — however, generics are probably safer — see below:

Marc Gravell's user avatar

For .NET 4.0 and higher, you can compare elements in array or tuples using the StructuralComparisons type:

Pang's user avatar

Yuliia Ashomok's user avatar

Recommending SequenceEqual is ok, but thinking that it may ever be faster than usual for(;;) loop is too naive.

Here is the reflected code:

As you can see it uses 2 enumerators and fires numerous method calls which seriously slow everything down. Also it doesn’t check length at all, so in bad cases it can be ridiculously slower.

Compare moving two iterators with beautiful

and you will know what I mean about performance.

It can be used in cases where performance is really not so critical, maybe in unit test code, or in cases of some short list in rarely called methods.

SequenceEqual can be faster. Namely in the case where almost all of the time, both arrays have indeed the same length and are not the same object.

It’s still not the same functionality as the OP’s function, as it won’t silently compare null values.

I know this is an old topic, but I think it is still relevant, and would like to share an implementation of an array comparison method which I feel strikes the right balance between performance and elegance.

The idea here is to check for all of the early out conditions first, then fall back on SequenceEqual . It also avoids doing extra branching and instead relies on boolean short-circuit to avoid unecessary execution. I also feel it looks clean and is easy to understand.

Also, by using ICollection for the parameters, it will work with more than just arrays.

    The Overflow Blog
Linked
Related

Most asked in [c#]

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.3.11.43304

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

как сравнить элементы одного массива между собой

Другие ответы правильно решают вашу проблему обнаружения, если есть какие-либо повторяющиеся записи, использующие GroupBy . Однако, если вы намереваетесь заменить эти дублирующиеся записи на новую несуществующую запись в массиве, вы можете использовать методы ниже:

Этот код гарантирует, что массив elements всегда будет иметь уникальные значения.

Примечание. — Цикл do. while продолжает генерировать случайные числа, если он не находит уникальное число. Поэтому, если размер вашего массива больше, чем диапазон генерируемых случайных чисел, вы застрянете в бесконечном цикле.

Используя силу linq, вы можете использовать GroupBy для поиска дубликатов.

Кроме того, Enumerable.Range — это быстрый способ создания списков.

Если вам нужно обработать дубликаты, вы можете повторить их и использовать .Key

Самый простой способ сравнить массивы в C #

В Java Arrays.equals() позволяет легко сравнивать содержимое двух базовых массивов (для всех базовых типов доступны перегрузки).

Есть ли такое в C #? Есть ли в C # «волшебный» способ сравнения содержимого двух массивов?

задан 12 июля ’10, 19:07

Читать:
Как зайти на почту без подтверждения телефона

В теги добавлено ‘.net’, потому что этот метод можно использовать в других подобных языках, основанных на .net. — Evan Plaice

Всем, кто читает это, имейте в виду, что принятый ответ использует SequenceEqual. SequenceEqual не только проверяет, содержат ли они одинаковые данные, но и содержат ли они одинаковые данные в одном и том же порядке — John Demetriou

17 ответы

Вы можете использовать Enumerable.SequenceEqual . Это работает для любого IEnumerable<T> , а не только массивы.

ответ дан 11 мая ’20, 13:05

Это работает, только если они находятся в одном порядке — Джон Деметриу

SequenceEqual не может быть хорошим выбором с точки зрения производительности, потому что его текущая реализация может полностью перечислить один из его источников, если они отличаются только длиной. С массивами мы могли бы проверить Length равенство во-первых, чтобы избежать перечисления массивов разной длины только для того, чтобы в итоге получить false . — Фредерик

@ Фредерик, факт SequenceEqual сначала сравнит длины, если оба перечисления реализуют ICollection См. github.com/dotnet/runtime/blob/main/src/libraries/System.Linq/… — Quinmars

@quinmars, этот ответ касался .Net Framework, .Net Core не существовало в 2010 году. Соответствующий код здесь. Тем не менее, хорошо знать, что этот момент в .Net Core изменился. Но это остается верным для .Net Framework. — Фредерик

ответ дан 11 мая ’20, 13:05

Имейте в виду, что это вызывает нулевые аргументы, поэтому убедитесь, что не предполагаете, что new int[] <1>.SequenceEquals(null) == false — Сара

Также для массивов (и кортежей) вы можете использовать новые интерфейсы из .NET 4.0: IstructuralComparable и IСтруктурный. С их помощью вы можете не только проверять равенство массивов, но и сравнивать их.

Создан 13 июля ’10, 07:07

Для массивов типов с большими значениями их использование снижает производительность, потому что их текущая реализация будет упаковывать каждое значение для сравнения. — Фредерик

Если вы .NET 4.0 и выше вы можете сравнивать элементы в массиве или кортежах, используя Структурные сравнения Тип:

SequenceEqual вернет истину только в том случае, если выполнены два или два условия.

  1. Они содержат одинаковые элементы.
  2. Элементы расположены в том же порядке.

Если вы хотите только проверить, содержат ли они одни и те же элементы независимо от их порядка, и ваша проблема относится к типу

Содержит ли values2 все значения, содержащиеся в values1?

вы можете использовать метод расширения LINQ Enumerable.Except а затем проверьте, имеет ли результат какое-либо значение. Вот пример

А также, используя это, вы также автоматически получаете различные предметы. Две птицы с одним камнем.

Имейте в виду, если вы выполняете свой код следующим образом

вы получите разные результаты.

В моем случае у меня есть локальная копия массива, и я хочу проверить, было ли что-то удалено из исходного массива, поэтому я использую этот метод.

ответ дан 03 мая ’16, 07:05

Если вы хотите справиться null изящно вводя данные и игнорируя порядок элементов, попробуйте следующее решение:

Тестовый код выглядит так:

ответ дан 19 окт ’20, 17:10

Для модульных тестов вы можете использовать CollectionAssert.AreEqual вместо Assert.AreEqual .

Это, наверное, самый простой способ.

ответ дан 25 мая ’17, 04:05

Для некоторых приложений может быть лучше:

Недооцененное решение! Это идеально подходит для многих случаев использования. — Томас

@Thomas на самом деле они голосовали против несколько раз;) — Алексковельский

Предполагая, что равенство массивов означает, что оба массива имеют равные элементы с одинаковыми индексами, существует SequenceEqual ответ IStructuralEquatable ответ.

Но у обоих есть недостатки с точки зрения производительности.

SequenceEqual реализация в .Net Framework не будет сокращать, когда массивы имеют разную длину, и поэтому она может перечислить один из них полностью, сравнивая каждый из его элементов.
При этом, в зависимости от вкуса .Net (например, .Net5), это может быть ярлык, см. этот комментарий. Итак, для современного проекта .Net, SequenceEqual должен быть хорошим выбором.

IStructuralEquatable не является универсальным и может вызывать упаковку каждого сравниваемого значения. Более того, его не очень просто использовать, и он уже требует кодирования некоторых вспомогательных методов, скрывающих его.

Может быть лучше с точки зрения производительности использовать что-то вроде:

Но, конечно, это тоже не какой-то «волшебный способ» проверки равенства массивов.

Так что в настоящее время нет эквивалента Java Arrays.equals() в .Net.

ответ дан 07 мар ’21, в 17:03

Это решение LINQ работает, не знаю, как его производительность сравнивается с SequenceEquals. Но он обрабатывает массивы разной длины, и .All выйдет на первый элемент, который не равен, без итерации по всему массиву.

Я искал, чтобы определить, имеют ли два набора эквивалентное содержимое в любом порядке. Это означало, что для каждого элемента в наборе A было равное количество элементов с этим значением в обоих наборах. Я хотел учесть дубликаты (поэтому <1,2,2,3>и <1,2,3,3>не следует считать «одинаковым»).

Это то, что я придумал (обратите внимание, что IsNullOrEmpty — еще один статический метод расширения, который возвращает истину, если перечисляемое значение равно нулю или имеет 0 элементов):

поэлементно сравнить? что о

Замените условие (a == b) чем-нибудь, что вы хотите сравнить в a и b.

ответ дан 15 апр.

Он не обрабатывает массивы разной длины (может некорректно давать true ) и расширение null массивы (произойдет сбой). — Фредерик

Я делал это в визуальных студиях, и это отлично работало; сравнение индексов массивов по индексу с коротким этим кодом.

вывод будет; Соответствующие числа 7 Несовпадающие числа 3

ответ дан 24 дек ’16, 05:12

Не обрабатывает массивы разной длины (выйдет из строя), null массивы (тоже будут сбой), и он делает что-то еще, кроме того, что попросил OP. Он только просил узнать равенство, не считая, сколько предметов различаются или совпадают. — Фредерик

Вы можете использовать Enumerable.Intersect :

Я не думаю, что это то, о чем просит OP. Как это сравнить массивы? Он только определяет, есть ли у массивов какой-либо общий элемент. Это вряд ли эквивалент Java Arrays.equals() . — Мартин Прикрыл

Проверьте ответ на этой теме который преобразует один из массивов в HashSet и использует SetEquals для сравнения с другим массивом.

ответ дан 24 мар ’21, в 12:03

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

Это дает, например, следующие результаты:

Он перечисляет каждое перечислимое число только один раз, но создает словарь для каждого перечислимого и повторяет их тоже один раз. Мне было бы интересно узнать, как это улучшить.

Похожие статьи