Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.05.2013, 17:26   #1
NEXit
Пользователь
 
Регистрация: 06.12.2011
Сообщений: 14
По умолчанию Удалить из массива все элементы, встречающиеся менее двух раз

Всем привет помогите решить наброски есть.
Дан целочисленный массив, состоящий из n элементов. Удалить из массива все элементы, встречающиеся менее двух раз. Решите задачу данной группы, оформив решение в виде функций ввода, вывода и обработки массивов.
Код:
void vvod(int *A,int n) //Функция ввода
{    int i;
    printf ("Vvedite elementi massiva:\n");
    for (i=0;i<n;++i)
    {        printf("A[%d]=",i+1);
        scanf ("%d", &A[i]);
      }}
void vyvod(int *A, int n) //вывод
{    int i;
    printf("[");
    for (i=0;i<n;++i)
    {
        printf ("%5.1d ", A[i]);
    }
    printf ("]");}
int main()
{    int n,i,A[500];
    printf ("Vvedite kolichestvo elementov massiva:\n");
    scanf ("%d", &n);
    vvod(A,n);
    f(A,n);//ТУТ нужна сама функция 
    vyvod(A,n);
    getch ();
}
Хелп !!!!
NEXit вне форума Ответить с цитированием
Старый 28.05.2013, 17:36   #2
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Такой функции (с таким прототипом) быть не может: нельзя просто "удалить" элементы из массива.
Может подойти функция, которая принимает указатель на начало массива, его длину, указатель на начало второго массива той же длины, переписывает в этот массив только повторяющиеся элементы и возвращает число переписанных элементов:
Код:
int main()
{    int n,i,A[500]; //Э, а нам гарантируют, что n<=500?
    int m, B[500];
    printf ("Vvedite kolichestvo elementov massiva:\n");
    scanf ("%d", &n);
    vvod(A,n);
    m = f(A,n,B);//ТУТ нужна сама функция 
    vyvod(B,m);
    getch ();
}
Теперь о самой функции f. Проще всего (хотя и катастрофически неоптимально) для каждого элемента считать, сколько элементов, равных ему, есть в исходном массиве, и только если это число больше 1 - переносить в новый массив:
Код:
int f(int* A, int n, int* B){
  int m=0; //Пока мы в B ничего не переписали
  for(int i=0; i<n; ++i){
    //Проверяем элемент A[i] - сколько равных ему во всём A
    //Если возникают трудности - сделайте отдельную функцию
    
    //Если их больше одного,
      //Переносим его в B[m]
      //Увеличиваем m на 1
  }
  return m;
}
Abstraction вне форума Ответить с цитированием
Старый 28.05.2013, 17:40   #3
NEXit
Пользователь
 
Регистрация: 06.12.2011
Сообщений: 14
По умолчанию

Цитата:
Сообщение от Abstraction Посмотреть сообщение
Такой функции (с таким прототипом) быть не может: нельзя просто "удалить" элементы из массива.
Может подойти функция, которая принимает указатель на начало массива, его длину, указатель на начало второго массива той же длины, переписывает в этот массив только повторяющиеся элементы и возвращает число переписанных элементов:
Код:
int main()
{    int n,i,A[500]; //Э, а нам гарантируют, что n<=500?
    int m, B[500];
    printf ("Vvedite kolichestvo elementov massiva:\n");
    scanf ("%d", &n);
    vvod(A,n);
    m = f(A,n,B);//ТУТ нужна сама функция 
    vyvod(B,m);
    getch ();
}
Теперь о самой функции f. Проще всего (хотя и катастрофически неоптимально) для каждого элемента считать, сколько элементов, равных ему, есть в исходном массиве, и только если это число больше 1 - переносить в новый массив:
Код:
int f(int* A, int n, int* B){
  int m=0; //Пока мы в B ничего не переписали
  for(int i=0; i<n; ++i){
    //Проверяем элемент A[i] - сколько равных ему во всём A
    //Если возникают трудности - сделайте отдельную функцию
    
    //Если их больше одного,
      //Переносим его в B[m]
      //Увеличиваем m на 1
  }
  return m;
}
Спасибо сейчас посмотрю
NEXit вне форума Ответить с цитированием
Старый 28.05.2013, 17:42   #4
VIK_aka_TOR
Участник клуба
 
Аватар для VIK_aka_TOR
 
Регистрация: 30.01.2011
Сообщений: 1,578
По умолчанию

не проверял, но что-то подобное

Код:
void f(int *A, int n)
{
bool flag; // дли идентификации дубля
int i,j = 0;  

while (i < n){
  flag = false; // ставим сперва что повтора нету
  while (j < n){
    if ((a[j] == a[i] ) && (j != i) )
        {flag = true;
          break; }// выходим из цикла для экономии программного времени
     }
   if !flag then{ // если дубля не было
    for (j:= i to n) // сдвигаем элементы после него на 1 позицию вперед
     a[j] = a[j+1];
     n--; // и -1 к количеству элементов
    }
  }
}
самого удаления нету, просто сдвиг влево идет уменьшение количества отображаемых элементов...
пишу код не только за печеньки
VIK_aka_TOR вне форума Ответить с цитированием
Старый 28.05.2013, 17:47   #5
NEXit
Пользователь
 
Регистрация: 06.12.2011
Сообщений: 14
По умолчанию

Вот есть для не уникальных
Код:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void print_arr(int * p,int array_size)
/* Функция вывода на экран массива */
{
 int i;
 for (i = 0; i < array_size; i++)
 printf("%d ",p[i]);
 printf("\n");
}

void fill_arr(int * p,int array_size)
/* Функция заполнения массива случайными числами */
{
 int i;
 for (i = 0; i < array_size; i++)
  {
  p[i] = rand() % 10;
  }

}
void kill_double(int *p, int size)
/* Функция удаления не уникальных элементов из массива */
{
 int *res = NULL; //Массив результатов
 int tmp,i,j;
 int count = 0;
 int k = 0;
 int len = 0;
 /* Отмечаем не уникальные элементы */
 for (i = 0; i < size; i++)
 {
  tmp = p[i];
  for (j = 0; j < size; j++)
  {
   if (p[j] == tmp)
   {
    count++;
    if (count > 1 && p[j] != -1)
    {
     p[j] = -1;//Отмечаем -1 не уникальный элемент
     len++; //кол-во лишних элементов
    }//end if
   }//end if
  }//end for
 count = 0;
 }
 /* Удаляем не уникальные элементы */
 res = (int*)malloc(sizeof(int)*(size - len)); //выделяем память под новый массив
 for (i = 0; i < size; i++)
 {
  if (p[i] != -1)
  {
   res[k]=p[i];
   k++;
  }
 }
 p = res;
 print_arr(p,size-len);
}

void main()
{
 srand(time(NULL));
 int array_size; /* Переменные массива №1 и №2 */
 int *p1 = NULL  ; /* Указатель на массив №1 */

 /* Ввод размера массива */
 printf("Введите размер массива \n");
 scanf("%d",&array_size);

 /* Выделение памяти под массивы */
 p1 = (int*)malloc(sizeof(int)*array_size);
 /* Заполнение массива №1 и №2 случайными числами */
 fill_arr(p1,array_size);

 /* Вывод массивов на экран */
 printf("Ваш массив \n");
 print_arr(p1,array_size);

 kill_double(p1,array_size); //Убираем из массива дублированные элементы
}
NEXit вне форума Ответить с цитированием
Старый 28.05.2013, 17:49   #6
VIK_aka_TOR
Участник клуба
 
Аватар для VIK_aka_TOR
 
Регистрация: 30.01.2011
Сообщений: 1,578
По умолчанию

привиденный выше вами код вкорне отличается от того что вы в самом начале темы выдали, т.к. тут уже динамические массивы, нежели статические... тут и удалить можно...
пишу код не только за печеньки
VIK_aka_TOR вне форума Ответить с цитированием
Старый 28.05.2013, 17:51   #7
VIK_aka_TOR
Участник клуба
 
Аватар для VIK_aka_TOR
 
Регистрация: 30.01.2011
Сообщений: 1,578
По умолчанию

Цитата:
Сообщение от Abstraction Посмотреть сообщение
Теперь о самой функции f. Проще всего (хотя и катастрофически неоптимально) для каждого элемента считать, сколько элементов, равных ему, есть в исходном массиве, и только если это число больше 1 - переносить в новый массив
зачем считать сколько, можно попросту проверять есть ли хоть еще один такой-же, но не он сам что бы был это... быстрее получается так)
пишу код не только за печеньки
VIK_aka_TOR вне форума Ответить с цитированием
Старый 28.05.2013, 17:55   #8
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
Вот есть для не уникальных
Плохой код. Функция kill_double ничего не удаляет, а создаёт (внутри себя) двойника, в котором удаляет требуемое, после чего его распечатывает. Её следовало бы назвать print_unique, или как-то так.
Финал
Код:
 p = res;
 print_arr(p,size-len);
}
- особенно нехорош. p=res производит такое впечатление, будто мы меняем переданный массив (хотя на самом деле это не так) и, хуже всего, выделенная под временный массив память не очищается перед выходом из функции, налицо утечка памяти (memory leak).

Цитата:
Код:
    for (j:= i to n) // сдвигаем элементы после него на 1 позицию вперед
     a[j] = a[j+1];
     n--; // и -1 к количеству элементов
Всё это, конечно, хорошо - но ведь потом мы вернёмся из функции - и как вызывающий код должен разобраться в том, что мы сделали с массивом? В частности, где он после этих операций кончается - уже неизвестно.
Abstraction вне форума Ответить с цитированием
Старый 28.05.2013, 17:59   #9
VIK_aka_TOR
Участник клуба
 
Аватар для VIK_aka_TOR
 
Регистрация: 30.01.2011
Сообщений: 1,578
По умолчанию

Цитата:
В частности, где он после этих операций кончается - уже неизвестно.
по поводу того что n не изменится при данном вызове/описании функции то да, но в самом коде же учтено изменение n )))
не испытываю симпатии из-за подобного к сишным функция, изза этих указателей, ссылок и адресов... но нужно бороться с неграмотностью)
пишу код не только за печеньки
VIK_aka_TOR вне форума Ответить с цитированием
Старый 28.05.2013, 17:59   #10
NEXit
Пользователь
 
Регистрация: 06.12.2011
Сообщений: 14
По умолчанию

Да плохой пример нашел. Сегодня 4 задачи сделал с блок схемами завтра надо сдавать вот не могу последние 2 сделать(
NEXit вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Дан массив из n элементов. Удалить из массива все элементы, встречающиеся ровно два раза Koroleva_E Помощь студентам 0 02.05.2013 13:50
Удалить из массива элементы встречающиеся менее трёх раз morfei74 Общие вопросы C/C++ 1 13.01.2013 10:29
Удалить из массива все элементы встречающиеся более двух раз. dimok5 Помощь студентам 0 15.03.2012 16:28
По массивам, SOS! из целочисленного массива удалить из массива элементы, встречающиеся менее 3-х раз prelest' Паскаль, Turbo Pascal, PascalABC.NET 1 23.05.2011 22:37
дан целочисленный массив N. Удалить из массива все элементы,встречающиеся [менее двух раз]1 Zevsnet Паскаль, Turbo Pascal, PascalABC.NET 6 16.01.2011 18:01