Найти дубликаты между массивами - PullRequest
7 голосов
/ 12 февраля 2010

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

, поэтому предположим, что массив A имеет три значения: a, b, c. и массив B имеет три значения: d, e, f.

мы уверены, что два значения будут одинаковыми. нас просят поместить эти четыре разных значения в массив размера 4, так что выходной массив C должен иметь в индексах 1 и 2 одинаковые значения из массивов A и B. и в индексах 0 и 3 он должен иметь разные значения массивов A и B. Я реализовал его, но на самом деле не удовлетворен этим решением ... у кого-нибудь есть идея лучшего решения? кроме того, который поместил бы мои счетчики в массив ...:)

int[] a = { 1, 201, 354 };
int[] b = { 404, 201, 354 };

int[] c = new int[4];

for (int i = 0; i < c.Length; i++)
{
    Console.WriteLine(c[i]);
}

Ответы [ 16 ]

0 голосов
/ 12 февраля 2010

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

int c1, c2, i;
c1 = a[0] == b[0] ? 0
                  : (a[0] == b[1] ? 1 : 2); // index of a[0] in array 'b'
c2 = a[1] == b[0] ? 0
                  : (a[1] == b[1] ? 1 : 2); // index of a[1] in array 'b'

for(i=0; i<2; i++)
    Console.WriteLine(a[i]);
Console.WriteLine(b[3-c1-c2]); // looks quite hacky but it is actually element of 'b' not in array 'a'
0 голосов
/ 12 февраля 2010

Я придумал это как первый черновик, но я думаю, что это может потребовать некоторого улучшения.Он также не удовлетворяет требованию наличия дубликатов в позициях 1 и 2 и уникальных чисел в 0 и 3 в массиве.Я думал, что выложу это в любом случае, чтобы вы могли понять, как это может выглядеть:

  int[] a = { 1, 201, 354 };
  int[] b = { 404, 201, 354 };

  int[] c = new int[ 4 ];

  // Start by just copying over one of the arrays completely.
  a.CopyTo( c, 0 );

  // Loop through b and compare each number against each
  // each number in a.
  foreach( int i in b )
  {
    // Assume that you're not dealing with a duplicate
    bool found = true;
    foreach( int j in a )
    {
      // If you find a duplicate, set found to false
      if( i == j )
      {
        found = false;
      }           
    }
    // If you haven't found a duplicate this is the
    // number you want - add it to the array.
    if (found == true)
    {
      c[3] = i;
    }
  }
0 голосов
/ 12 февраля 2010

Вместо counter1, counter2, counter3:

counter[3];

От этого многое становится легче. Вы можете ссылаться на все в циклах, чтобы начать с.

0 голосов
/ 12 февраля 2010
bool isUsed[6]={true, true, true, true, true, true};

int values[6];

int valuesCount = 0;

int i,j;

for( i = 0 ; i < 3 ; i++)
{
   bool goodValue = true;
   for ( j = 0; j < valuesCount; j++)
   {
       if(values[j] == a[i])
       {
           isUsed[j] = false;
           goodValue = false;
           break;
       }
   }
   if(goodValue)
   {
       values[valuesCount++]=a[i];
   }
}

//same for b[i]

for( i = 0 ; i < valuesCount; i++)
{ 
   if( isUsed[i] ) printf("%i ", values[i]);
}
0 голосов
/ 12 февраля 2010

Я почти уверен, что не понимаю вопроса.

Вы говорите:

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

На какие четыре различных значения вы ссылаетесь? Два одинаковых? Потому что именно к этому относится слово «эти».

Вы имеете в виду: взять 4 уникальных значения и поместить их в массив?

Так что:

1, 2, 3
2, 3, 4

становится:

1, 2, 3, 4?

Это просто:

int[] c = a.Concat(b).Distinct().ToArray();

При этом используются методы расширения Linq .NET 3.5. Если вы не используете .NET 3.5, вы можете сделать это:

Dictionary<int, int> c1 = new Dictionary<int, int>();
foreach (var x in a)
    c1[x] = 1;
foreach (var x in b)
    c1[x] = 1;
int[] c = new List<int>(c1.Keys).ToArray();

Теперь, если вам нужен следующий порядок:

  1. Первое значение, которое произошло только один раз
  2. Первое значение, которое произошло дважды
  3. Второе значение, которое произошло дважды
  4. Второе значение, которое произошло только один раз

Тогда, боюсь, у меня нет для вас однострочного текста, придется подумать еще немного.

Могу я спросить, каков контекст? Почему это требование?

0 голосов
/ 12 февраля 2010

Эта часть

    if (a[0] == b[0]) { counter0++; }
    if (a[0] == b[1]) { counter0++; }
    if (a[0] == b[2]) { counter0++; }

    if (a[1] == b[0]) { counter1++; }
    if (a[1] == b[1]) { counter1++; }
    if (a[1] == b[2]) { counter1++; }

    if (a[2] == b[0]) { counter2++; }
    if (a[2] == b[1]) { counter2++; }
    if (a[2] == b[2]) { counter2++; }

Возможно, можно переписать как

for (i=0; i<3; i++)
{
    for (j=0; j<3; j++)
    {
         switch(i)
         {
              case 0:
              if (a[i] == b[j]) { counter0++; }
              break;
              case 1:
              if (a[i] == b[j]) { counter1++; }
              break;
              case 2:
              if (a[i] == b[j]) { counter2++; }
              break;
          }
     }
}

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

Другим вариантом может быть LINQ, но я точно не знаю, как написать что-то подобное.

(Не пытался это скомпилировать, но идея ясна?)

UPDATE: Если бы вы могли поместить счетчики в массив, это могло бы сработать:

for (i=0; i<3; i++)
{
    for (j=0; j<3; j++)
    {
        if (a[i] == b[j]) { counters[i]++; }

     }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...