2015-05-31 2 views
1

Я написал код, чтобы удалить повторяющиеся значения и добавить 0 на место. Но я чувствую, что мой код должен быть намного лучше этого, если кто-нибудь может дать лучшее представление о разработке этого кода. Пожалуйста, предложите мне и посоветуйте мне.Удаление повторяющихся значений и добавление 0 на их место

  • Вход - 2,3,4,3,6
  • выход - 2,3,4,0,6

Вот мой код:

#include<stdio.h> 
int main() 
{ 
    int a[100],b[100]; 
    int i,j,size; 
    scanf("%d",&size); 
    for(i=0;i<size;i++) 
    { 
     scanf("%d",&a[i]); 
    } 

    for(i=0;i<size;i++) 
    { 
     b[i]=a[i]; 

    } 

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

    for(i=0;i<size;i++) 
     printf("%d\n",b[i]); 

    return 0; 
} 
+0

Одна оптимизация может использовать только один массив и модифицировать на 'a' вместо копирования в' b'. –

+0

@how реализовать это, потому что, я знаю, для большого количества цифр это сделает мою программу очень медленной. –

+0

Вы уже используете O (n^2). Можно проверить в том же массиве. –

ответ

0

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

#include<stdio.h> 
int main() 
{ 
    int a[100]; 
    int i,j,size,left; 
    scanf("%d",&size); 
    for(i=0;i<size;i++) 
    { 
     scanf("%d",&a[i]); 
    } 

    left = size; 
    for(i=0;i<size&&left>1;i++) // If there's only 1 left, it's not a duplicate 
    { 
     if(a[i] == 0) // No need to test these, already done 
     continue; 

     for(j=i+1,left=0;j<size;j++) 
     { 
     if(a[i]==a[j]) 
     { 
      a[j]=0; 
     } 
     if(a[j]!=0) 
      left++; // If we don't get here, there's nothing left to test 
     } 
    } 

    for(i=0;i<size;i++) 
     printf("%d\n",a[i]); 

    return 0; 
} 

Так что, в основном, не ищите 0 впереди текущей позиции, и при поиске чего-либо еще подсчитывают (отметьте на самом деле), если что-то осталось испытать.

+0

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

+0

Поскольку копирование одного массива в другой увеличивает временную сложность. –

+0

Если вам не нужно сохранять исходный массив, это проще ... Я сделал это, так как это ваш исходный код. Редактирование ответа ... – Amit

1

Очистить дубликаты, как они введены следующим образом, по сравнению с значениями введены до сих пор:

#include<stdio.h> 
int main() { 
    int a[100]; 
    int i,j,size; 
    scanf("%d",&size); 
    for(i=0;i<size;i++) 
    { 
     scanf("%d",&a[i]); 
     for(j=0;j<i;j++){ 
     if(a[j]==a[i]) { 
      a[i]=0; /* found duplicate among previous entries! */ 
      break; 
     } 
     } 
    } 
    for(i=0;i<size;i++) 
    printf("%d\n",a[i]); 
    return 0; 
} 
+0

Является ли это более эффективным, чем оригинальное решение? или просто «короче» кода?Кроме того, вопрос более общий, чем обработка ввода, речь идет о поиске и очистке дубликатов в массиве – Amit

+0

@Gregor nice. –

+0

@Amit: ну, это более короткий код (меньше места для ошибок ...). Плюс это больше пространства, экономя массив b целиком. И перерыв делает его эффективным в среднем. Вы можете использовать тот же подход, когда массив уже заполнен, конечно. –

0

Вот некоторые из моей идеи:

Решения 1:

Использования битного чтобы указать, произошло ли еще число. Например, на 32-битной машине 1 int имеет 32 бит, если ваш диапазон номеров составляет 1 ~ 1000, тогда вам нужно 32 int, вы можете изменить его диапазон, когда вы встретили большее число, на realloc().

Если ваш диапазон номеров невелик, то это вполне подходит.

Решение 2:

Магазин отсортирован числа в бинарном дереве, так что вы можете искать быстрее.

+0

похоже осуществимый сделаем это. –

+0

@ Эрик да это. Потому что пересечение в дереве довольно просто, чем массив. –

+0

@ Эрик ваше 2-е решение очень хорошее, но, вероятно, будет противодействовать «ограниченной» проблеме в исходном вопросе (массив размером <100). В широком масштабе BST является очевидной оптимизацией, хотя в зависимости от конкретных деталей проблемы может потребоваться балансирующий BST. – Amit

0

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

#include<stdio.h> 

int main() { 
    int a[100]; 
    int i,j,size; 
    scanf("%d",&size); 
    for(i=0;i<size;i++) { 
     scanf("%d",&a[i]); 
    } 

    for(i=1; i<size; i++) { 
     for(j=i-1; j>=0; j--) { 
      if(a[i]==a[j]) { 
       a[i]=0; 
       break; 
      }  
     } 
    } 

    for(i=0;i<size;i++) 
     printf("%d ",a[i]); 

    return 0; 
} 
+0

Это не будет иметь тот же результат, что и исходный образец (вы получите -2,0,4,3,6), но это легко решить, перевернув направление поиска. – Amit

+0

Нет, вы бы получили (2,0,4,3,6), если были использованы 'a [j] = 0', но не с' a [i] = 0', как я использовал. –

+0

@ Anindya, но затем он делает программу совершенно другой, потому что первое значение никогда не является дубликатом в списке, другие, которые появляются после этого, являются дубликатами; –

Смежные вопросы