(Есть ли подход O (1).) Учитывая массив символов, дайте алгоритм для удаления дубликатов [duplicate]

В то время как , что вызывает NullReferenceExceptions и подходит к avoid / fix , такое исключение было рассмотрено в других ответах, что многие программисты не имеют " t узнал еще, как независимо отлаживать такие исключения во время разработки.

В Visual Studio это обычно легко благодаря Visual Studio Debugger .


Во-первых, убедитесь, что правильная ошибка будет обнаружена - см. . Как разрешить нарушение «Исключение System.NullReferenceException» в VS2010? Примечание1

Затем либо Начать с отладки (F5) , либо Приложить [отладчик VS] к запуску процесса . Иногда может быть полезно использовать Debugger.Break , в котором будет предложено запустить отладчик.

Теперь, когда NullReferenceException выбрано (или необработанно), отладчик остановится ( помните правило, указанное выше?) в строке, на которой произошло исключение. Иногда ошибка может быть легко обнаружена.

Например, в следующей строке единственный код, который может , вызывает исключение, если myString имеет значение null. Это можно проверить, посмотрев окно Watch или выполнив выражения в окне Immediate Window .

var x = myString.Trim();

В более сложных случаях, таких как следуя ниже, вам нужно будет использовать один из методов выше (Watch или Immediate Windows) для проверки выражений, чтобы определить, было ли str1 пустым или если str2 имеет значение null.

var x = str1.Trim() + str2.Trim();

Once , где было выбрано исключение, это обычно тривиально по отношению к разуму назад, чтобы выяснить, где введенное значение null было [неправильно] -

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


1 Если Break on Throws слишком агрессивен и отладчик останавливается на NPE в библиотеке .NET или сторонних разработчиков, Break на User-Unhandled можно использовать для ограничения выловленных исключений. Кроме того, VS2012 представляет Just My Code , который я рекомендую также включить.

Если вы отлаживаете с включенным Just My Code, поведение немного отличается. При включенном Just My Code отладчик игнорирует исключения, связанные с привилегиями обычного языка (CLR) первого шанса, которые выходят за пределы My Code и не проходят через My Code

blockquote>

28
задан cletus 28 July 2010 в 13:43
поделиться

13 ответов

Проверять каждый элемент на каждый другой элемент

Наивное решение - проверять каждый элемент на каждый другой элемент. Это расточительно и дает решение O (n2), даже если вы только переходите вперед.

Сортировка, а затем удаление дубликатов

Лучшее решение сортирует массив, а затем проверяет каждый элемент рядом с ним, чтобы найти дубликаты. Выберите эффективную сортировку, и это O (n log n).

Недостаток решения на основе сортировки не поддерживается. Однако дополнительный шаг может позаботиться об этом. Поместите все записи (в уникальном отсортированном массиве) в хеш-таблицу, которая имеет доступ O (1). Затем перебираем исходный массив. Для каждого элемента проверьте, находится ли он в хеш-таблице. Если это так, добавьте его в результат и удалите из хеш-таблицы. Вы получите результирующий массив, который имеет порядок оригинала, причем каждый элемент находится в том же положении, что и его первое вхождение.

Линейные сортировки целых чисел

Если вы имея дело с целыми числами некоторого фиксированного диапазона, вы можете сделать еще лучше, используя сортировку radix. Если вы предполагаете, что все номера находятся в диапазоне от 0 до 1 000 000, например, вы можете выделить бит-вектор около 1000,001. Для каждого элемента в исходном массиве вы устанавливаете соответствующий бит на основе его значения (например, значение 13 приводит к установке 14-го бита). Затем перейдите к исходному массиву, проверьте, находится ли он в битовом векторе. Если это так, добавьте его в массив результатов и очистите этот бит от битового вектора. Это O (n) и пространство трейдинга для времени.

Решение хэш-таблицы

Это приводит нас к лучшему решению всего: сортировка на самом деле является отвлечением, хотя и полезным. Создайте хэш-таблицу с доступом O (1). Перейдите к исходному списку. Если он уже не в хэш-таблице, добавьте его в массив результатов и добавьте его в хеш-таблицу. Если он находится в хеш-таблице, игнорируйте его.

Это, безусловно, лучшее решение. Так почему же остальные? Потому что такие проблемы связаны с адаптацией знаний, которые у вас есть (или должны иметь) к проблемам, и их уточнения на основе предположений, которые вы принимаете в решении. Разработка решения и понимание мышления, стоящего за ним, гораздо полезнее, чем срывание решения.

Кроме того, хеш-таблицы не всегда доступны. Возьмите встроенную систему или что-то там, где пространство ОЧЕНЬ ограничено. Вы можете реализовать быструю сортировку в нескольких кодах операций, гораздо меньше, чем любая хеш-таблица.

71
ответ дан cletus 31 August 2018 в 16:42
поделиться

Обработать номера как ключи.

for each elem in array:
if hash(elem) == 1 //duplicate
  ignore it
  next
else
  hash(elem) = 1
  add this to resulting array 
end
Если вы знаете о таких данных, как диапазон чисел, и если он конечен, вы можете инициализировать этот большой массив с помощью ZERO.
array flag[N] //N is the max number in the array
for each elem in input array:
  if flag[elem - 1] == 0
    flag[elem - 1] = 1
    add it to resulatant array
  else
    discard it //duplicate
  end

1
ответ дан bhups 31 August 2018 в 16:42
поделиться

Вы можете использовать синтаксис «in» и «not in» в python, который делает его довольно простым.

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

li = map(int, raw_input().split(","))
a = []
for i in li:
    if i not in a:
        a.append(i)
print a
0
ответ дан Deepak Pathania 31 August 2018 в 16:42
поделиться
    indexOutput = 1;
    outputArray[0] = arrayInt[0];
    int j;
    for (int i = 1; i < arrayInt.length; i++) {            
        j = 0;
        while ((outputArray[j] != arrayInt[i]) && j < indexOutput) {
            j++;
        }
        if(j == indexOutput){
           outputArray[indexOutput] = arrayInt[i];
           indexOutput++;
        }         
    }
1
ответ дан dhayyati 31 August 2018 в 16:42
поделиться

Мое решение (O(N)) не использует дополнительную память, но массив должен быть отсортирован (мой класс использует алгоритм сортировки вставки, но это не имеет значения.):

  public class MyArray
        {
            //data arr
            private int[] _arr;
            //field length of my arr
            private int _leght;
            //counter of duplicate
            private int countOfDup = 0;
            //property length of my arr
            public int Length
            {
                get
                {
                    return _leght;
                }
            }

            //constructor
            public MyArray(int n)
            {
                _arr = new int[n];
                _leght = 0;
            }

            // put element into array
            public void Insert(int value)
            {
                _arr[_leght] = value;
                _leght++;
            }

            //Display array
            public void Display()
            {
                for (int i = 0; i < _leght; i++) Console.Out.Write(_arr[i] + " ");
            }

            //Insertion sort for sorting array
            public void InsertSort()
            {
                int t, j;
                for (int i = 1; i < _leght; i++)
                {
                    t = _arr[i];
                    for (j = i; j > 0; )
                    {
                        if (_arr[j - 1] >= t)
                        {
                            _arr[j] = _arr[j - 1];
                            j--;
                        }
                        else break;
                    }
                    _arr[j] = t;
                }
            }

            private void _markDuplicate()
            {
                //mark duplicate Int32.MinValue
                for (int i = 0; i < _leght - 1; i++)
                {
                    if (_arr[i] == _arr[i + 1])
                    {
                        countOfDup++;
                        _arr[i] = Int32.MinValue;
                    }
                }
            }

            //remove duplicates O(N) ~ O(2N) ~ O(N + N)
            public void RemoveDups()
            {
                _markDuplicate();
                if (countOfDup == 0) return; //no duplicate
                int temp = 0;

                for (int i = 0; i < _leght; i++)
                {
                    // if duplicate remember and continue
                    if (_arr[i] == Int32.MinValue) continue;
                    else //else need move 
                    {
                        if (temp != i) _arr[temp] = _arr[i];
                        temp++;
                    }
                }
                _leght -= countOfDup;
            }
        }

и Main

static void Main(string[] args)
{
     Random r = new Random(DateTime.Now.Millisecond);
     int i = 11;
     MyArray a = new MyArray(i);
     for (int j = 0; j < i; j++)
     {
        a.Insert(r.Next(i - 1));
     }

     a.Display();
     Console.Out.WriteLine();
     a.InsertSort();
     a.Display();
     Console.Out.WriteLine();
     a.RemoveDups();
     a.Display();

    Console.ReadKey();
}
0
ответ дан isxaker 31 August 2018 в 16:42
поделиться

Если вам не нужно сохранять исходный объект, вы можете его закодировать и создать новый массив уникальных значений. В C # используйте Список, чтобы получить доступ к требуемой функциональности. Это не самое привлекательное или интеллектуальное решение, но оно работает.

int[] numbers = new int[] {1,2,3,4,5,1,2,2,2,3,4,5,5,5,5,4,3,2,3,4,5};
List<int> unique = new List<int>();

foreach (int i in numbers)
     if (!unique.Contains(i))
          unique.Add(i);

unique.Sort();
numbers = unique.ToArray();
2
ответ дан Jonathon Reinhart 31 August 2018 в 16:42
поделиться

Я согласен с Cletus. Используйте QuickSort , затем удалите дубликаты

0
ответ дан Laramie 31 August 2018 в 16:42
поделиться

Это может быть сделано в амортизированном O (n) с использованием набора на основе хэш-таблицы.

Псевдоэкс:

s := new HashSet
c := 0
for each el in a
  Add el to s.
    If el was not already in s, move (copy) el c positions left.
    If it was in s, increment c. 
2
ответ дан Matthew Flaschen 31 August 2018 в 16:42
поделиться
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class testing {
    public static void main(String[] args) {
        EligibleOffer efg = new EligibleOffer();
        efg.setCode("1234");
        efg.setName("hey");
        EligibleOffer efg1 = new EligibleOffer();
        efg1.setCode("1234");
        efg1.setName("hey1");
        EligibleOffer efg2 = new EligibleOffer();
        efg2.setCode("1235");
        efg2.setName("hey");
        EligibleOffer efg3 = new EligibleOffer();
        efg3.setCode("1235");
        efg3.setName("hey");
        EligibleOffer[] eligibleOffer = { efg, efg1,efg2 ,efg3};
        removeDupliacte(eligibleOffer);
    }

    public static EligibleOffer[] removeDupliacte(EligibleOffer[] array) {
        List list = Arrays.asList(array);
        List list1 = new ArrayList();
        int len = list.size();
        for (int i = 0; i <= len-1; i++) {
            boolean isDupliacte = false;
            EligibleOffer eOfr = (EligibleOffer) list.get(i);
            String value = eOfr.getCode().concat(eOfr.getName());
            if (list1.isEmpty()) {
                list1.add(list.get(i));
                continue;
            }
            int len1 = list1.size();
            for (int j = 0; j <= len1-1; j++) {
                EligibleOffer eOfr1 = (EligibleOffer) list1.get(j);
                String value1 = eOfr1.getCode().concat(eOfr1.getName());
                if (value.equals(value1)) {
                    isDupliacte = true;
                    break;
                }
                System.out.println(value+"\t"+value1);
            }
            if (!isDupliacte) {
                list1.add(eOfr);
            }
        }
        System.out.println(list1);
        EligibleOffer[] eligibleOffer = new EligibleOffer[list1.size()];
        list1.toArray(eligibleOffer);
        return eligibleOffer;
    }
}
0
ответ дан Nivi 31 August 2018 в 16:42
поделиться
Time O(n) space O(n) 

#include <iostream>
    #include<limits.h>
    using namespace std;
    void fun(int arr[],int size){

        int count=0;
        int has[100]={0};
        for(int i=0;i<size;i++){
            if(!has[arr[i]]){
               arr[count++]=arr[i];
               has[arr[i]]=1;
            }
        }
     for(int i=0;i<count;i++)
       cout<<arr[i]<<" ";
    }

    int main()
    {
        //cout << "Hello World!" << endl;
        int arr[]={4, 8, 4, 1, 1, 2, 9};
        int size=sizeof(arr)/sizeof(arr[0]);
        fun(arr,size);

        return 0;
    }
0
ответ дан rjnitt 31 August 2018 в 16:42
поделиться

Это сегмент кода i, созданный на C ++, попробуйте его

#include <iostream>

using namespace std;

int main()
{
   cout << " Delete the duplicate" << endl; 

   int numberOfLoop = 10;
   int loopCount =0;
   int indexOfLargeNumber = 0;
   int largeValue = 0;
   int indexOutput = 1;

   //Array to hold the numbers
   int arrayInt[10] = {};
   int outputArray [10] = {};

   // Loop for reading the numbers from the user input
   while(loopCount < numberOfLoop){       
       cout << "Please enter one Integer number" << endl;
       cin  >> arrayInt[loopCount];
       loopCount = loopCount + 1;
   }



    outputArray[0] = arrayInt[0];
    int j;
    for (int i = 1; i < numberOfLoop; i++) {            
        j = 0;
        while ((outputArray[j] != arrayInt[i]) && j < indexOutput) {
            j++;
        }
        if(j == indexOutput){
           outputArray[indexOutput] = arrayInt[i];
           indexOutput++;
        }         
    }

   cout << "Printing the Non duplicate array"<< endl;

   //Reset the loop count
   loopCount =0;

   while(loopCount < numberOfLoop){ 
       if(outputArray[loopCount] != 0){
        cout <<  outputArray[loopCount] << endl;
    }     

       loopCount = loopCount + 1;
   }   
   return 0;
}
0
ответ дан Vanji 31 August 2018 в 16:42
поделиться
0
ответ дан Ved Prakash 31 August 2018 в 16:42
поделиться

Используйте реализацию Set. HashSet , TreeSet или LinkedHashSet , если его Java.

0
ответ дан Zaki 31 August 2018 в 16:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: