Programing

알고리즘 : 배열에서 중복 정수를 제거하는 효율적인 방법

crosscheck 2020. 9. 13. 10:04
반응형

알고리즘 : 배열에서 중복 정수를 제거하는 효율적인 방법


Microsoft와의 인터뷰에서이 문제가 발생했습니다.

임의의 정수 배열이 주어지면 중복 된 숫자를 제거하고 원래 배열의 고유 한 숫자를 반환하는 알고리즘을 C로 작성합니다.

예 : 입력 : {4, 8, 4, 1, 1, 2, 9}출력 :{4, 8, 1, 2, 9, ?, ?}

한 가지주의 할 점은 예상 알고리즘이 배열을 먼저 정렬 할 필요가 없다는 것입니다. 요소가 제거되면 다음 요소도 앞으로 이동해야합니다. 어쨌든, 요소가 앞으로 이동 한 배열의 꼬리에있는 요소의 값은 무시할 수 있습니다.

업데이트 : 결과는 원래 배열로 반환되어야하며 도우미 데이터 구조 (예 : 해시 테이블)를 사용해서는 안됩니다. 그러나 주문 보존은 필요하지 않은 것 같습니다.

업데이트 2 : 왜 이러한 비현실적인 제약이 있는지 궁금해하는 사람들을 위해 이것은 인터뷰 질문이었고 이러한 모든 제약은 내가 다른 아이디어를 어떻게 생각 해낼 수 있는지보기 위해 사고 과정에서 논의됩니다.


어때 :

void rmdup(int *array, int length)
{
    int *current , *end = array + length - 1;

    for ( current = array + 1; array < end; array++, current = array + 1 )
    {
        while ( current <= end )
        {
            if ( *current == *array )
            {
                *current = *end--;
            }
            else
            {
                current++;
            }
        }
    }
}

O (n ^ 2) 이하 여야합니다.


내 여자 친구가 제안한 해결책은 병합 정렬의 변형입니다. 유일한 수정 사항은 병합 단계에서 중복 된 값을 무시하는 것입니다. 이 솔루션은 O (n log n)입니다. 이 접근 방식에서는 정렬 / 중복 제거가 함께 결합됩니다. 그러나 그것이 어떤 차이를 만드는지 확실하지 않습니다.


예전에 한번 올렸는데 꽤 멋있기 때문에 여기서 재현하겠습니다. 해싱을 사용하여 제자리에 설정된 해시와 같은 것을 만듭니다. 겨드랑이 공간에서 O (1)이 보장되며 (재귀는 꼬리 호출 임) 일반적으로 O (N) 시간 복잡도입니다. 알고리즘은 다음과 같습니다.

  1. 배열의 첫 번째 요소를 가져 오면 이것이 센티널이됩니다.
  2. 각 요소가 해시에 해당하는 위치에 있도록 가능한 한 나머지 배열의 순서를 변경하십시오. 이 단계가 완료되면 중복 항목이 발견됩니다. 센티넬과 동일하게 설정하십시오.
  3. 인덱스가 해시와 동일한 모든 요소를 ​​배열의 시작 부분으로 이동합니다.
  4. 배열의 첫 번째 요소를 제외하고 sentinel과 동일한 모든 요소를 ​​배열의 끝으로 이동합니다.
  5. 올바르게 해시 된 요소와 중복 요소 사이에 남는 것은 충돌로 인해 해시에 해당하는 인덱스에 배치 할 수없는 요소입니다. 이러한 요소를 처리하려면 재귀하십시오.

이것은 해싱에 병리학 적 시나리오가없는 경우 O (N)으로 표시 될 수 있습니다. 중복이 없더라도 각 재귀에서 요소의 약 2/3가 제거됩니다. 각 재귀 수준은 O (n)이며 small n은 남은 요소의 양입니다. 유일한 문제는 실제로 중복이 거의 없을 때 즉, 많은 충돌이있을 때 빠른 정렬보다 느리다는 것입니다. 그러나 엄청난 양의 중복이있을 때는 놀랍도록 빠릅니다.

편집 : D의 현재 구현에서 hash_t는 32 비트입니다. 이 알고리즘에 대한 모든 것은 전체 32 비트 공간에서 해시 충돌이 거의 없다고 가정합니다. 그러나 충돌은 모듈러스 공간에서 자주 발생할 수 있습니다. 그러나이 가정은 합리적인 크기의 데이터 세트에 대해 모두 사실입니다. 키가 32 비트보다 작거나 같으면 자체 해시가 될 수 있으므로 전체 32 비트 공간에서 충돌이 불가능합니다. 더 큰 경우 문제가 될 수 있도록 32 비트 메모리 주소 공간에 충분히 들어갈 수 없습니다. 저는 D의 64 비트 구현에서 hash_t가 64 비트로 증가 할 것이라고 가정합니다. 여기서 데이터 세트는 더 클 수 있습니다. 또한 이것이 문제가된다면 각 재귀 수준에서 해시 함수를 변경할 수 있습니다.

다음은 D 프로그래밍 언어로 구현 된 것입니다.

void uniqueInPlace(T)(ref T[] dataIn) {
    uniqueInPlaceImpl(dataIn, 0);
}

void uniqueInPlaceImpl(T)(ref T[] dataIn, size_t start) {
    if(dataIn.length - start < 2)
        return;

    invariant T sentinel = dataIn[start];
    T[] data = dataIn[start + 1..$];

    static hash_t getHash(T elem) {
        static if(is(T == uint) || is(T == int)) {
            return cast(hash_t) elem;
        } else static if(__traits(compiles, elem.toHash)) {
            return elem.toHash;
        } else {
            static auto ti = typeid(typeof(elem));
            return ti.getHash(&elem);
        }
    }

    for(size_t index = 0; index < data.length;) {
        if(data[index] == sentinel) {
            index++;
            continue;
        }

        auto hash = getHash(data[index]) % data.length;
        if(index == hash) {
            index++;
            continue;
        }

        if(data[index] == data[hash]) {
            data[index] = sentinel;
            index++;
            continue;
        }

        if(data[hash] == sentinel) {
            swap(data[hash], data[index]);
            index++;
            continue;
        }

        auto hashHash = getHash(data[hash]) % data.length;
        if(hashHash != hash) {
            swap(data[index], data[hash]);
            if(hash < index)
                index++;
        } else {
            index++;
        }
    }


    size_t swapPos = 0;
    foreach(i; 0..data.length) {
        if(data[i] != sentinel && i == getHash(data[i]) % data.length) {
            swap(data[i], data[swapPos++]);
        }
    }

    size_t sentinelPos = data.length;
    for(size_t i = swapPos; i < sentinelPos;) {
        if(data[i] == sentinel) {
            swap(data[i], data[--sentinelPos]);
        } else {
            i++;
        }
    }

    dataIn = dataIn[0..sentinelPos + start + 1];
    uniqueInPlaceImpl(dataIn, start + swapPos + 1);
}

한 가지 더 효율적인 구현

int i, j;

/* new length of modified array */
int NewLength = 1;

for(i=1; i< Length; i++){

   for(j=0; j< NewLength ; j++)
   {

      if(array[i] == array[j])
      break;
   }

   /* if none of the values in index[0..j] of array is not same as array[i],
      then copy the current value to corresponding new position in array */

  if (j==NewLength )
      array[NewLength++] = array[i];
}

이 구현에서는 배열을 정렬 할 필요가 없습니다. 또한 중복 요소가 발견되면 그 이후의 모든 요소를 ​​한 위치만큼 이동할 필요가 없습니다.

이 코드의 출력은 NewLength 크기의 array []입니다.

여기서 우리는 배열의 두 번째 요소부터 시작하여이 배열까지 배열의 모든 요소와 비교합니다. 입력 배열을 수정하기 위해 추가 인덱스 변수 'NewLength'를 보유하고 있습니다. NewLength 변수는 0으로 초기화됩니다.

array [1]의 요소는 array [0]과 비교됩니다. 서로 다르면 array [NewLength]의 값이 array [1]로 수정되고 NewLength가 증가합니다. 동일하면 NewLength가 수정되지 않습니다.

따라서 배열 [1 2 1 3 1]이 있으면

'j'루프의 첫 번째 패스에서 array [1] (2)는 array0과 비교되고 2는 array [NewLength] = array [1]에 기록되므로 NewLength = 2이므로 배열은 [1 2]가됩니다.

'j'루프의 두 번째 패스에서 array [2] (1)는 array0 및 array1과 비교됩니다. 여기서 array [2] (1)과 array0은 동일한 루프이므로 여기서 중단됩니다. 따라서 배열은 NewLength = 2이므로 [1 2]가됩니다.

등등


우수한 O 표기법을 찾고 있다면 O (n log n) 정렬로 배열을 정렬 한 다음 O (n) 순회를 수행하는 것이 가장 좋은 방법 일 수 있습니다. 정렬하지 않고 O (n ^ 2)를보고 있습니다.

편집 : 정수만 수행하는 경우 기수 정렬을 수행하여 O (n)을 얻을 수도 있습니다.


1. O (n log n) 시간에 O (1) 추가 공간 사용

예를 들면 다음과 같습니다.

  • 먼저 제자리 O (n log n) 정렬을 수행합니다.
  • 그런 다음 목록을 한 번 살펴보고 목록의 시작 부분에 모든 백의 첫 번째 인스턴스를 작성하십시오.

ejel의 파트너가이를 수행하는 가장 좋은 방법은 단순화 된 병합 단계를 사용하는 내부 병합 정렬이며, 예를 들어 질문의 의도 일 것입니다. 입력을 개선 할 능력없이 가능한 한 효율적으로이를 수행하기 위해 새 라이브러리 함수를 작성하며, 입력의 종류에 따라 해시 테이블없이 그렇게하는 것이 유용한 경우가있을 수 있습니다. 그러나 나는 이것을 실제로 확인하지 않았습니다.

2. O (n) 시간에 O (lots) 추가 공간 사용

  • 모든 정수를 담을 수있을만큼 충분히 큰 0 배열을 선언
  • 어레이를 한 번 살펴보십시오.
  • 각 정수에 대해 해당 배열 요소를 1로 설정하십시오.
  • 이미 1이면 해당 정수를 건너 뜁니다.

이것은 몇 가지 의심스러운 가정이있는 경우에만 작동합니다.

  • 저렴하게 메모리를 제로화하는 것이 가능하거나 int의 크기가 개수에 비해 작습니다.
  • OS에 256 ^ sizepof (int) 메모리를 요청하시면됩니다.
  • 거대하다면 정말 효율적으로 캐시합니다.

잘못된 대답이지만 입력 요소가 많지만 모두 8 비트 정수 (또는 16 비트 정수일 수도 있음) 인 경우 가장 좋은 방법 일 수 있습니다.

3. O (작은)-같은 여분의 공간, O (n)-쉬운 시간

# 2로 해시 테이블을 사용합니다.

4. 명확한 방법

요소 수가 적 으면 다른 코드가 더 빨리 작성되고 더 빨리 읽을 수 있으면 적절한 알고리즘을 작성하는 것이 유용하지 않습니다.

예 : 모든 동일한 요소를 제거하는 각 고유 요소 (즉, 첫 번째 요소, 두 번째 요소 (첫 번째 요소의 중복) 등)에 대한 배열을 살펴 봅니다. O (1) 추가 공간, O (n ^ 2) 시간.

예 : 이를 수행하는 라이브러리 함수를 사용하십시오. 효율성은 쉽게 사용할 수있는 항목에 따라 다릅니다.


음, 기본 구현은 매우 간단합니다. 모든 요소를 ​​살펴보고 나머지 요소에 중복이 있는지 확인하고 나머지 요소를 이동합니다.

끔찍한 비효율적이며 출력 또는 정렬 / 이진 트리에 대한 도우미 배열로 속도를 높일 수 있지만 허용되지 않는 것 같습니다.


C ++를 사용할 수있는 경우를 호출 한 std::sort다음를 호출 std::unique하면 응답이 제공됩니다. 시간 복잡도는 정렬의 경우 O (N log N)이고 고유 순회의 경우 O (N)입니다.

그리고 C ++가 테이블에서 벗어난 경우 이러한 동일한 알고리즘이 C로 작성되는 것을 막는 것은 없습니다.


메모리를 희생하려는 경우 단일 순회에서이를 수행 할 수 있습니다. 해시 / 연관 배열에서 정수를 보았는지 여부를 간단히 계산할 수 있습니다. 이미 숫자를 본 경우, 이동하면서 제거하거나, 보지 못한 숫자를 새 배열로 이동하여 원래 배열의 이동을 피하십시오.

Perl에서 :

foreach $i (@myary) {
    if(!defined $seen{$i}) {
        $seen{$i} = 1;
        push @newary, $i;
    }
}

함수의 반환 값은 고유 한 요소의 수 여야하며 모두 배열의 맨 앞에 저장됩니다. 이 추가 정보가 없으면 중복 항목이 있는지조차 알 수 없습니다.

외부 루프의 각 반복은 배열의 한 요소를 처리합니다. 고유 한 경우 배열의 앞쪽에 있고 중복 된 경우 배열의 마지막 처리되지 않은 요소로 덮어 씁니다. 이 솔루션은 O (n ^ 2) 시간에 실행됩니다.

#include <stdio.h>
#include <stdlib.h>

size_t rmdup(int *arr, size_t len)
{
  size_t prev = 0;
  size_t curr = 1;
  size_t last = len - 1;
  while (curr <= last) {
    for (prev = 0; prev < curr && arr[curr] != arr[prev]; ++prev);
    if (prev == curr) {
      ++curr;
    } else {
      arr[curr] = arr[last];
      --last;
    }
  }
  return curr;
}

void print_array(int *arr, size_t len)
{
  printf("{");
  size_t curr = 0;
  for (curr = 0; curr < len; ++curr) {
    if (curr > 0) printf(", ");
    printf("%d", arr[curr]);
  }
  printf("}");
}

int main()
{
  int arr[] = {4, 8, 4, 1, 1, 2, 9};
  printf("Before: ");
  size_t len = sizeof (arr) / sizeof (arr[0]);
  print_array(arr, len);
  len = rmdup(arr, len);
  printf("\nAfter: ");
  print_array(arr, len);
  printf("\n");
  return 0;
}

다음은 Java 버전입니다.

int[] removeDuplicate(int[] input){

        int arrayLen = input.length;
        for(int i=0;i<arrayLen;i++){
            for(int j = i+1; j< arrayLen ; j++){
                if(((input[i]^input[j]) == 0)){
                    input[j] = 0;
                }
                if((input[j]==0) && j<arrayLen-1){
                        input[j] = input[j+1];
                        input[j+1] = 0;
                    }               
            }
        }       
        return input;       
    }

값을 앞뒤로 불필요하게 복사하지 않도록 배열은 분명히 오른쪽에서 왼쪽으로 "순회"되어야합니다.

무제한 메모리 sizeof(type-of-element-in-array) / 8가있는 경우 각 비트가 이미 해당 값을 만났는지 여부를 나타내도록 바이트에 비트 배열을 할당 할 수 있습니다 .

그렇지 않다면 배열을 순회하고 각 값을 그 뒤에 오는 값과 비교 한 다음 중복이 발견되면이 값을 모두 제거하는 것보다 더 나은 것을 생각할 수 없습니다. 이것은 O (n ^ 2) (또는 O ((n ^ 2-n) / 2) ) 근처에 있습니다.

IBM 에 좀 가까운 주제에 대한 기사 가 있습니다.


보자 :

  • 최소 / 최대 할당을 찾기위한 O (N) 통과
  • 찾은 비트 어레이
  • O (N) 패스 스와핑 중복을 끝냅니다.

이것은 O (N log N) 알고리즘을 사용하고 추가 스토리지없이 한 번에 수행 할 수 있습니다.

요소 a[1]에서 a[N]. 각 단계 i에서의 왼쪽에있는 모든 요소 a[i]는 정렬 된 요소 힙을 구성 a[0]합니다 a[j]. 한편, 두 번째 인덱스 j(처음에는 0)는 힙 크기를 추적합니다.

검사 a[i]및 지금 요소를 차지 힙, 삽입 a[0]a[j+1]. 요소가 삽입 될 a[k]때 동일한 값을 갖는 중복 요소 가 발견 a[i]되면 힙에 삽입하지 마십시오 (즉, 폐기하십시오). 그렇지 않으면 힙에 삽입하십시오. 이제 한 요소만큼 증가하고 이제 a[0]to a[j+1]및 increment로 구성 j됩니다.

이 방식으로 계속하여 i모든 배열 요소가 검사되고 힙에 삽입 될 때까지 증가 a[0]하여 a[j]. j힙의 마지막 요소의 인덱스이고 힙에는 고유 한 요소 값만 포함됩니다.

int algorithm(int[] a, int n)
{
    int   i, j;  

    for (j = 0, i = 1;  i < n;  i++)
    {
        // Insert a[i] into the heap a[0...j]
        if (heapInsert(a, j, a[i]))
            j++;
    }
    return j;
}  

bool heapInsert(a[], int n, int val)
{
    // Insert val into heap a[0...n]
    ...code omitted for brevity...
    if (duplicate element a[k] == val)
        return false;
    a[k] = val;
    return true;
}

예제를 보면 결과 배열이 원래 요소 순서를 유지하기 때문에 정확히 요청 된 것이 아닙니다. 그러나이 요구 사항이 완화되면 위의 알고리즘이 트릭을 수행해야합니다.


여기 내 해결책이 있습니다.

///// find duplicates in an array and remove them

void unique(int* input, int n)
{
     merge_sort(input, 0, n) ;

     int prev = 0  ;

     for(int i = 1 ; i < n ; i++)
     {
          if(input[i] != input[prev])
               if(prev < i-1)
                   input[prev++] = input[i] ;                         
     }
}

Java에서는 이렇게 해결할 것입니다. 이것을 C로 작성하는 방법을 모릅니다.

   int length = array.length;
   for (int i = 0; i < length; i++) 
   {
      for (int j = i + 1; j < length; j++) 
      {
         if (array[i] == array[j]) 
         {
            int k, j;
            for (k = j + 1, l = j; k < length; k++, l++) 
            {
               if (array[k] != array[i]) 
               {
                  array[l] = array[k];
               }
               else
               {
                  l--;
               }
            }
            length = l;
         }
      }
   }

다음은 어떻습니까?

int* temp = malloc(sizeof(int)*len);
int count = 0;
int x =0;
int y =0;
for(x=0;x<len;x++)
{
    for(y=0;y<count;y++)
    {
        if(*(temp+y)==*(array+x))
        {
            break;
        }
    }
    if(y==count)
    {
        *(temp+count) = *(array+x);
        count++;
    }
}
memcpy(array, temp, sizeof(int)*len);

임시 배열을 선언하고 모든 요소를 ​​원래 배열에 다시 복사하기 전에 여기에 요소를 넣으려고합니다.


문제를 검토 한 후 여기에 도움이 될 수있는 델파이 방식이 있습니다.

var
A: Array of Integer;
I,J,C,K, P: Integer;
begin
C:=10;
SetLength(A,10);
A[0]:=1; A[1]:=4; A[2]:=2; A[3]:=6; A[4]:=3; A[5]:=4;
A[6]:=3; A[7]:=4; A[8]:=2; A[9]:=5;

for I := 0 to C-1 do
begin
  for J := I+1 to C-1 do
    if A[I]=A[J] then
    begin
      for K := C-1 Downto J do
        if A[J]<>A[k] then
        begin
          P:=A[K];
          A[K]:=0;
          A[J]:=P;
          C:=K;
          break;
        end
        else
        begin
          A[K]:=0;
          C:=K;
        end;
    end;
end;

//tructate array
setlength(A,C);
end;

다음 예는 문제를 해결합니다.

def check_dump(x):
   if not x in t:
      t.append(x)
      return True

t=[]

output = filter(check_dump, input)

print(output)
True

import java.util.ArrayList;


public class C {

    public static void main(String[] args) {

        int arr[] = {2,5,5,5,9,11,11,23,34,34,34,45,45};

        ArrayList<Integer> arr1 = new ArrayList<Integer>();

        for(int i=0;i<arr.length-1;i++){

            if(arr[i] == arr[i+1]){
                arr[i] = 99999;
            }
        }

        for(int i=0;i<arr.length;i++){
            if(arr[i] != 99999){

                arr1.add(arr[i]);
            }
        }

        System.out.println(arr1);
}
    }

This is the naive (N*(N-1)/2) solution. It uses constant additional space and maintains the original order. It is similar to the solution by @Byju, but uses no if(){} blocks. It also avoids copying an element onto itself.

#include <stdio.h>
#include <stdlib.h>

int numbers[] = {4, 8, 4, 1, 1, 2, 9};
#define COUNT (sizeof numbers / sizeof numbers[0])

size_t undup_it(int array[], size_t len)
{
size_t src,dst;

  /* an array of size=1 cannot contain duplicate values */
if (len <2) return len; 
  /* an array of size>1 will cannot at least one unique value */
for (src=dst=1; src < len; src++) {
        size_t cur;
        for (cur=0; cur < dst; cur++ ) {
                if (array[cur] == array[src]) break;
                }
        if (cur != dst) continue; /* found a duplicate */

                /* array[src] must be new: add it to the list of non-duplicates */
        if (dst < src) array[dst] = array[src]; /* avoid copy-to-self */
        dst++;
        }
return dst; /* number of valid alements in new array */
}

void print_it(int array[], size_t len)
{
size_t idx;

for (idx=0; idx < len; idx++)  {
        printf("%c %d", (idx) ? ',' :'{' , array[idx] );
        }
printf("}\n" );
}

int main(void) {    
    size_t cnt = COUNT;

    printf("Before undup:" );    
    print_it(numbers, cnt);    

    cnt = undup_it(numbers,cnt);

    printf("After undup:" );    
    print_it(numbers, cnt);

    return 0;
}

This can be done in a single pass, in O(N) time in the number of integers in the input list, and O(N) storage in the number of unique integers.

Walk through the list from front to back, with two pointers "dst" and "src" initialized to the first item. Start with an empty hash table of "integers seen". If the integer at src is not present in the hash, write it to the slot at dst and increment dst. Add the integer at src to the hash, then increment src. Repeat until src passes the end of the input list.


Insert all the elements in a binary tree the disregards duplicates - O(nlog(n)). Then extract all of them back in the array by doing a traversal - O(n). I am assuming that you don't need order preservation.


Use bloom filter for hashing. This will reduce the memory overhead very significantly.


In JAVA,

    Integer[] arrayInteger = {1,2,3,4,3,2,4,6,7,8,9,9,10};

    String value ="";

    for(Integer i:arrayInteger)
    {
        if(!value.contains(Integer.toString(i))){
            value +=Integer.toString(i)+",";
        }

    }

    String[] arraySplitToString = value.split(",");
    Integer[] arrayIntResult = new Integer[arraySplitToString.length];
    for(int i = 0 ; i < arraySplitToString.length ; i++){
        arrayIntResult[i] = Integer.parseInt(arraySplitToString[i]);
    }

output: { 1, 2, 3, 4, 6, 7, 8, 9, 10}

hope this will help


Create a BinarySearchTree which has O(n) complexity.


First, you should create an array check[n] where n is the number of elements of the array you want to make duplicate-free and set the value of every element(of the check array) equal to 1. Using a for loop traverse the array with the duplicates, say its name is arr, and in the for-loop write this :

{
    if (check[arr[i]] != 1) {
        arr[i] = 0;
    }
    else {
        check[arr[i]] = 0;
    }
}

With that, you set every duplicate equal to zero. So the only thing is left to do is to traverse the arr array and print everything it's not equal to zero. The order stays and it takes linear time (3*n).


Given an array of n elements, write an algorithm to remove all duplicates from the array in time O(nlogn)

Algorithm delete_duplicates (a[1....n])
//Remove duplicates from the given array 
//input parameters :a[1:n], an array of n elements.

{

temp[1:n]; //an array of n elements. 

temp[i]=a[i];for i=1 to n

 temp[i].value=a[i]

temp[i].key=i

 //based on 'value' sort the array temp.

//based on 'value' delete duplicate elements from temp.

//based on 'key' sort the array temp.//construct an array p using temp.

 p[i]=temp[i]value

  return p.

In other of elements is maintained in the output array using the 'key'. Consider the key is of length O(n), the time taken for performing sorting on the key and value is O(nlogn). So the time taken to delete all duplicates from the array is O(nlogn).


this is what i've got, though it misplaces the order we can sort in ascending or descending to fix it up.

#include <stdio.h>
int main(void){
int x,n,myvar=0;
printf("Enter a number: \t");
scanf("%d",&n);
int arr[n],changedarr[n];

for(x=0;x<n;x++){
    printf("Enter a number for array[%d]: ",x);
    scanf("%d",&arr[x]);
}
printf("\nOriginal Number in an array\n");
for(x=0;x<n;x++){
    printf("%d\t",arr[x]);
}

int i=0,j=0;
// printf("i\tj\tarr\tchanged\n");

for (int i = 0; i < n; i++)
{
    // printf("%d\t%d\t%d\t%d\n",i,j,arr[i],changedarr[i] );
    for (int j = 0; j <n; j++)
    {   
        if (i==j)
        {
            continue;

        }
        else if(arr[i]==arr[j]){
            changedarr[j]=0;

        }
        else{
            changedarr[i]=arr[i];

        }
    // printf("%d\t%d\t%d\t%d\n",i,j,arr[i],changedarr[i] );
    }
    myvar+=1;
}
// printf("\n\nmyvar=%d\n",myvar);
int count=0;
printf("\nThe unique items:\n");
for (int i = 0; i < myvar; i++)
{
        if(changedarr[i]!=0){
            count+=1;
            printf("%d\t",changedarr[i]);   
        }
}
    printf("\n");
}

It'd be cool if you had a good DataStructure that could quickly tell if it contains an integer. Perhaps a tree of some sort.

DataStructure elementsSeen = new DataStructure();
int elementsRemoved = 0;
for(int i=0;i<array.Length;i++){
  if(elementsSeen.Contains(array[i])
    elementsRemoved++;
  else
    array[i-elementsRemoved] = array[i];
}
array.Length = array.Length - elementsRemoved;

참고URL : https://stackoverflow.com/questions/1532819/algorithm-efficient-way-to-remove-duplicate-integers-from-an-array

반응형