se(vero) - pagina 6

 
Georgiy Merts:

Non so...

Secondo me, sia questi blocchi "vuoti" che i "cicli infiniti" (sia for che while) sono un cattivo stile di programmazione, pericoloso per gli errori potenzialmente difficili da calcolare.

L'operatore di controllo delle condizioni del ciclo non dovrebbe essere privo di significato, ma avere un certo peso. Se abbiamo un "ciclo infinito", significa che ci sono alcune uscite e interruzioni aggiuntive all'interno del ciclo e non sono sempre ovvie. A proposito, neanche a me piace l'operatore break - uso sempre l 'operatore continue in un ciclo.


E come è stato detto qui l'offuscamento del codice è semplicemente infantile... Grandi programmatori-copisti riuniti qui che hanno paura che qualcuno venda il loro codice o ottenga milioni di dollari in altri modi... L'orgoglio è uno dei peccati capitali!

non sono d'accordo.
Prova a riscrivere questo codice senza il ciclo infinito e la pausa

int ArrayDeleteVal(int &a[],const int val) 
  {
   int size=ArraySize(a);
   int i=0,start,s,count;
   while(i<size && a[i]!=val) i++; // ищем первый элемент массива со значением val
   if(i==size) return size;
   start=i; i++;
   while(i<size && a[i]==val) i++; // ищем элемент массива со значением, не равным val
   if(i==size) {ArrayResize(a,start); return start;}
   s=i; i++;
   for(;;)
     {
      while(i<size && a[i]!=val) i++; // ищем элемент массива со значением val
      count=i-s;
      if(count>6) { ArrayCopy(a,a,start,s,count); start+=count;} // если нужно скопировать более 6 элементов, то имеет смысл воспользоваться ArrayCopy
      else for(; s<i; start++,s++) a[start]=a[s];                // иначе простой цикл
      if(i==size) break;
      i++;
      while(i<size && a[i]==val) i++; // ищем элемент массива со значением, не равным val
      if(i<size) s=i; else break;
      i++;
     }
   if(start<size) ArrayResize(a,start); else start=size;
   return(start);
  }
 
Nikolai Semko:

non sono d'accordo.
Prova a riscrivere questo codice senza il ciclo infinito e la pausa

Un compito interessante.

A mio parere, il codice presentato è piuttosto "opaco" e difficile da capire, anche se la struttura è chiara per me, e la funzione è utile.

A prima vista, il ciclo dovrebbe essere while (i<size) {....}, ma non l'ho ancora capito bene.

Non appena ci metterò le mani sopra, lo farò.

 
Georgiy Merts:

Un compito interessante.

A mio parere, il codice presentato è piuttosto "opaco" e difficile da capire, anche se la struttura è chiara per me e la funzione è utile.

A prima vista, il ciclo dovrebbe essere while (i<size) {....}, ma non l'ho ancora capito bene.

Appena avrò tempo, lo farò.

La funzione rimuove tutti i valori val dall'array a[] e lo compatta, rimuovendo i "buchi" degli elementi cancellati senza cambiare la sequenza dei dati.

 
Nikolai Semko:

La funzione cancella tutti i valori val dall'array a[] e lo compatta, rimuovendo i "buchi" dagli elementi cancellati senza cambiare la sequenza dei dati.

Sì, sì, te l'ho detto - lo scopo è chiaro, la funzione stessa è utile. Ora non posso ancora, più tardi capirò come funziona, e la riscriverò senza ciclo infinito. Bene, e poi - scriverò la mia variante di funzione, come scriverei io.

 
Georgiy Merts:

Sì, sì, te l'ho detto - lo scopo è chiaro, la funzione stessa è utile. Ora non posso ancora, più tardi sistemerò il mio lavoro e lo riscriverò senza loop infinito. Bene, e poi - scriverò la mia versione della funzione, come la scriverei io.

il codice è stato preso da qui. C'è stata una competizione spontanea un anno e mezzo fa.

 
Nikolai Semko:

non sono d'accordo.
Prova a riscrivere questo codice senza il ciclo infinito e la pausa


/// навскидку, даже не проверял
void ArrayDeleteVal(int &arr[],int val)
{
   int size=ArraySize(arr);
   int count=0;   // кол-во удалённых
   for(int i=0;i<size;i++) {
      if (arr[i]==val) count++;
      else if (count) {
         arr[i-count]=arr[count];
      }
   }
   ArrayResize(arr,size-count);
}
 
Maxim Kuznetsov:


Sì, è chiaro che ci sono varianti più compatte, ma più lente.
La tua variante è 2-3 volte più lenta della precedente e c'è un errore da qualche parte, perché dà un checksum sbagliato.
Stiamo parlando dell'opzione più veloce senza HashSet.


2020.04.08 14:15:35.829 ArrayDeleteValue1 (EURUSD,D1)   === Тест с сохранением порядка ===
2020.04.08 14:15:35.829 ArrayDeleteValue1 (EURUSD,D1)   
2020.04.08 14:15:35.977 ArrayDeleteValue1 (EURUSD,D1)   вариант Pastushak   : Контрольная сумма = 7225.757267; элементов - 998994; время выполнения - 144668 микросекунд
2020.04.08 14:15:35.981 ArrayDeleteValue1 (EURUSD,D1)   вариант Korotky     : Контрольная сумма = 7225.757267; элементов - 998994; время выполнения -   2416 микросекунд
2020.04.08 14:15:35.985 ArrayDeleteValue1 (EURUSD,D1)   вариант Fedoseev    : Контрольная сумма = 7225.757267; элементов - 998994; время выполнения -   1675 микросекунд
2020.04.08 14:15:35.988 ArrayDeleteValue1 (EURUSD,D1)   вариант Semko       : Контрольная сумма = 7225.757267; элементов - 998994; время выполнения -    797 микросекунд
2020.04.08 14:15:35.991 ArrayDeleteValue1 (EURUSD,D1)   вариант Nikitin     : Контрольная сумма = 7225.757267; элементов - 998994; время выполнения -   1866 микросекунд
2020.04.08 14:15:35.997 ArrayDeleteValue1 (EURUSD,D1)   вариант Vladimir    : Контрольная сумма = 7225.757267; элементов - 998994; время выполнения -   3453 микросекунд
2020.04.08 14:15:36.006 ArrayDeleteValue1 (EURUSD,D1)   вариант Peter       : Контрольная сумма = 7225.757267; элементов - 998994; время выполнения -   7633 микросекунд
2020.04.08 14:15:36.009 ArrayDeleteValue1 (EURUSD,D1)   вариант fann95      : Контрольная сумма = 7225.757267; элементов - 998994; время выполнения -   1135 микросекунд
2020.04.08 14:15:36.013 ArrayDeleteValue1 (EURUSD,D1)   вариант Kuznetsov   : Контрольная сумма = 7156.067670; элементов - 998994; время выполнения -   2368  микросекунд
2020.04.08 14:15:36.017 ArrayDeleteValue1 (EURUSD,D1)   вариант Kuznetsov1  : Контрольная сумма = 7219.503559; элементов - 1000000; время выполнения -   1874 микросекунд
2020.04.08 14:15:36.021 ArrayDeleteValue1 (EURUSD,D1)   вариант Kuznetsov2  : Контрольная сумма = 7225.757267; элементов - 998994; время выполнения -   2554 микросекунд
2020.04.08 14:15:36.021 ArrayDeleteValue1 (EURUSD,D1)   
2020.04.08 14:15:36.021 ArrayDeleteValue1 (EURUSD,D1)   === Порядок в массиве не сохраняется ===
2020.04.08 14:15:36.024 ArrayDeleteValue1 (EURUSD,D1)   вариант Kuznetsov3  : Контрольная сумма = 7224.813498; элементов - 998994; время выполнения -    735 микросекунд
2020.04.08 14:15:36.027 ArrayDeleteValue1 (EURUSD,D1)   вариант Semko2      : Контрольная сумма = 7224.813498; элементов - 998994; время выполнения -   1408 микросекунд
File:
 
Georgiy Merts:

Non so...

Secondo me, sia questi blocchi "vuoti" che i "cicli infiniti" (sia for che while) sono un cattivo stile di programmazione, pericoloso per gli errori potenzialmente difficili da calcolare.

L'operatore di controllo delle condizioni del ciclo non dovrebbe essere privo di significato, ma avere un certo peso. Se abbiamo un "ciclo infinito", significa che ci sono alcune uscite e interruzioni aggiuntive all'interno del ciclo e non sono sempre ovvie. A proposito, neanche a me piace l'operatore break - uso sempre l 'operatore continue in un ciclo.


E come è stato detto qui l'offuscamento del codice è semplicemente infantile... Grandi programmatori-copisti riuniti qui che hanno paura che qualcuno venda il loro codice o ottenga milioni di dollari in altri modi... L'orgoglio è uno dei peccati capitali!

Sì....
 
Maxim Kuznetsov:


Maxim, non funziona così, ci dovrebbero essere 2 cicli, altrimenti non c'è modo. Prima si rimuovono gli elementi non necessari, poi si "rimpicciolisce" l'array verso l'alto (float). Il secondo ciclo è dentro il primo.

 

Un costrutto for implica il controllo di una condizione e l'uscita prima che il ciclo inizi.

Un costrutto while comporta il controllo di una condizione e l'uscita prima che il ciclo finisca.

Un ciclo infinito implica il controllo della condizione e l'uscita in qualsiasi punto del ciclo.

Motivazione: