Очистка массива от заданного (ых) элементов - страница 5

 
Konstantin Nikitin:
Ну чисто о поставленной задаче. Удалить значение и пустые

ещё функцию добавить, чтобы можно фильтровать по критерию и захорошеет. Можно будет даже в коллекцию утащить :-)

что-то типа

int arrayFilter(T &data[], const T value, bool (*cmp)(const T&,const T&)=NotEqual<T>)

чтобы например вытащить все значения большие 3-х:  arrayFilter<long>(array,3,GreaterThen<long>)

не уверен что шаблоны MQL легко позволят такое сделать

 
TheXpert:

не навязываю.

Спасибо, Вы сегодня любезны :-)

По задаче. Имхо удобнее оперировать с таким типом из коллекции данных как CArrayDouble. Мой пример:

//--- https://www.mql5.com/ru/docs/standardlibrary/datastructures/carraydouble
#include <Arrays\ArrayDouble.mqh>
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   double delta=1e-3;
   CArrayDouble ArrDouble;
   ArrDouble.Delta(delta);
   double src_arr[]={1,2,3,6,9,5,6,3,25,6,8,7,4};
   double value_to_delete=3.0;
   if(ArrDouble.AddArray(src_arr))
     {
      ArrDouble.Sort();
      if(ArrDouble.IsSorted())
        {
         int first_idx,last_idx;
         first_idx=ArrDouble.SearchFirst(value_to_delete);
         last_idx=ArrDouble.SearchLast(value_to_delete);
         if(first_idx>=0)
           {
            PrintFormat("\nЭлементов до удаления: %d",ArrDouble.Total());
            if(ArrDouble.DeleteRange(first_idx,last_idx))
                  PrintFormat("Удалено элементов: %d",last_idx-first_idx+1);             
            PrintFormat("Элементов после удаления: %d",ArrDouble.Total());         
           }
        }
     }
  }
//+------------------------------------------------------------------+

Правда есть недостаток. На выходе получим отсортированный массив.

 
Denis Kirichenko:
охх, иногда лучше промолчать и показаться дураком, чем...
 
TheXpert:
охх, иногда лучше промолчать и показаться дураком, чем...

чем что либо сказать и развеять все сомнения....

 
Vladimir Pastushak:

Есть массив содержащий набор данных по типу 1,2,3,6,9,5,6,3,25,6,8,7,4 нужно удалить например значения 3 и на выходе получить тот же массив без 3 и пустых мест...

Я ищу самый быстрый способ очистки массива от ненужных значений...

На ум приходит такой пример

Может есть способы экономнее и быстрее ?

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

Потом делайте ArrayResize() с учетом количества стертых значений. 

Зы. Значения которые нужно стирать не переносите. Можно переносить влево все значения, кроме тех, что стираете. 

Сдвиг значений влево должен быть равен количеству стертых ячеек.

 
Vladimir Pastushak:

Глупый вопрос, это не заданный вопрос.

У меня есть несколько вариантов решения задачи, но я продолжаю искать лучшие решения и учиться у других.

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

Сам вопрос сформулирован неверно. Задача не в удалении повторяющихся значений (задача уровня ОГЭ) а в нечто большем, по всей видимости актуализируете список валидных элементов. Раз так, то и вопрос совсем иначе должен звучать. Вы же запутываете и вводите в заблуждение участников и прежде всего себя: навязывайте участникам неверное решение в принципе и просите его сделать эффективным.

 
Реter Konow:

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

Потом делайте ArrayResize() с учетом количества стертых значений. 

Зы. Значения которые нужно стирать не переносите. Можно переносить влево все значения, кроме тех, что стираете. 

Сдвиг значений влево должен быть равен количеству стертых ячеек.

 int Arr[20] = 1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2;
 int deleted;
//-------------- 
for(int a1 = 0; a1 < ArraySize(Arr); a1++)
  {
   if(deleted)Arr[a1] = Arr[a1 + deleted];
   
   if(Arr[a1] == 3)deleted++; 
  }
//-------------- 
ArrayResize(Arr, ArraySize(Arr) - deleted);

Проверьте этот вариант.

 

Сорри. Там похоже строчки надо местами поменять:


 int Arr[20] = 1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2;
 int deleted;
//-------------- 
for(int a1 = 0; a1 < ArraySize(Arr); a1++)
  {
   if(Arr[a1] == 3)deleted++; 

   if(deleted)Arr[a1] = Arr[a1 + deleted];
  }
//-------------- 
ArrayResize(Arr, ArraySize(Arr) - deleted);
 
Реter Konow:

Сорри. Там похоже строчки надо местами поменять:

Загадка: Сколько будет у Буратино яблок, если Мальвина даст ему два, а папа Карло три яблока?
Ответ: Десять. Исходные переменные нужно инициализировать. 

 
Реter Konow:

Сорри. Там похоже строчки надо местами поменять:


Еще доработка:

int Arr[20] = {1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2};
int deleted;
//-------------- 
for(int a1 = 0; a1 < ArraySize(Arr); a1++)
  {
   if(Arr[a1] == 3)
     {
      if(deleted)a1-= deleted;//Cмещение назад.
      deleted++; 
     }
   if(deleted)Arr[a1] = Arr[a1 + deleted];
  }
//-------------- 
ArrayResize(Arr, ArraySize(Arr) - deleted);
Причина обращения: