Se è una gara di velocità, offrirò la mia variante...
La tua variante è effettivamente la più veloce, ma contiene un bug: se tutti gli elementi di un array sono uguali a un filtro, la tua funzione uscirà dall'array.
Offrirò la mia variante, è un po' più lenta della tua:
int ArrayModify(int &a[],constint v)
{
int size=ArraySize(a)-1;
int j=0;
int total=size;
for(int i=0;i<size;i++)
{
while(a[i+j]==v && j<total)
{
j++;
size--;
}
a[i]=a[i+j];
}
size=ArrayResize(a,size);
return(size);
}
2018.11.13 17:16:38.618 massiv v1 (EURUSD,M1) test my=1512090 2018.11.13 17:16:40.083 massiv v1 (EURUSD,M1) test alien=1464941
Sono diversi anni che fai questo tipo di domande. Hai imparato molto? Scusate, ma è evidente che siete ancora al livello dei byte e degli array elementari.
La domanda stessa è formulata in modo scorretto. Il compito non è quello di rimuovere i valori ripetuti (compito del livello GCE) ma in qualcosa di molto più grande, è necessario aggiornare la lista degli elementi validi. Se è così, la domanda dovrebbe suonare completamente diversa. Confondete e ingannate i partecipanti e, prima di tutto, voi stessi: imponete ai partecipanti una soluzione sbagliata in linea di principio e chiedete di renderla efficace.
Non faccio programmazione per il gusto di programmare, non ho l'obiettivo di diventare un mega-programmatore e di essere intelligente sui forum.
Cosa non capite nella domanda: cancellare un array di elementi definiti?
La tua variante è effettivamente la più veloce, ma contiene un bug: se tutti gli elementi di un array sono uguali a un filtro, la tua funzione uscirà dall'array.
Ti suggerisco la mia variante, è un po' più lenta della tua:
2018.11.13 17:16:38.618 massiv v1 (EURUSD,M1) test my=1512090 2018.11.13 17:16:40.083 massiv v1 (EURUSD,M1) test alien=1464941
Sì, grazie. Corretto.
int ArrayDeleteVal(int &a[],constint val) // вариант Semko
{
int size=ArraySize(a);
int i=0,start,s,count;
while(i<size && a[i]!=val) i++; // ищем первый элемент массива со значением valif(i==size) return size;
start=i; i++;
while(i<size && a[i]==val) i++; // ищем элемент массива со значением, не равным valif(i==size) {ArrayResize(a,0); return0;}
s=i; i++;
while(true)
{
while(i<size && a[i]!=val) i++; // ищем элемент массива со значением val
count=i-s;
if(count>6) { ArrayCopy(a,a,start,s,count); start+=count;} // если нужно скопировать более 6 элементов, то имеет смысл воспользоваться ArrayCopyelsefor(; s<i; start++,s++) a[start]=a[s]; // иначе простой циклif(i==size) break;
i++;
while(i<size && a[i]==val) i++; // ищем элемент массива со значением, не равным valif(i<size) s=i; elsebreak;
i++;
}
if(start<size) ArrayResize(a,start); else start=size;
return(start);
}
Solo che anche voi avete un errore da qualche parte, perché il checksum non coincide perché manca un elemento da qualche parte. Non ha funzionato dove.
2018.11.1310:07:27.757 ArrayDeleteValue (EURUSD,D1) вариант Pastushak: Контрольная сумма = 495782577; элементов - 999027; время выполнения = 156757 микросекунд
2018.11.1310:07:27.761 ArrayDeleteValue (EURUSD,D1) вариант Korotky: Контрольная сумма = 495782577; элементов - 999027; время выполнения = 2338 микросекунд
2018.11.1310:07:27.764 ArrayDeleteValue (EURUSD,D1) вариант Fedoseev: Контрольная сумма = 495782577; элементов - 999027; время выполнения = 1839 микросекунд
2018.11.1310:07:27.766 ArrayDeleteValue (EURUSD,D1) вариант Semko: Контрольная сумма = 495782577; элементов - 999027; время выполнения = 782 микросекунд
2018.11.1310:07:27.770 ArrayDeleteValue (EURUSD,D1) вариант Pavlov: Контрольная сумма = 495781718; элементов - 999026; время выполнения = 2886 микросекунд
2018.11.1310:07:27.773 ArrayDeleteValue (EURUSD,D1) вариант Nikitin: Контрольная сумма = 495782577; элементов - 999027; время выполнения = 2355 микросекунд
Nikolai Semko: In entrambi i casi, ogni elemento viene trascinato al massimo una volta.
Speravo che qualcuno fosse interessato all'approccio DBMS e lo controllasse, non ho aspettato. Ho dovuto farlo io stesso.
int ArrayDelV (int &a[],constint val) { // вариант Vladimirbool Flags[]; // массив пометок на удалениеint N, NewN, i, j;
N=ArraySize(a);
ArrayResize(Flags,N);
//if (ArrayInitialize(Flags,false)!=N) return(-1);
NewN=N; // Сколько останетсяfor (i=0;i<N;i++) {if (a[i]==val) {Flags[i]=true; NewN--;}}
j=0;
for (i=0;i<N;i++) {if (Flags[i]) {a[j]=a[i]; j++;}}
ArrayResize(a,NewN);
return(NewN);
}
Inserito ArrayDeleteValue.mq5 nel tuo checker, è due volte peggio del tuo. Ho pensato al motivo e ho sistemato due righe in modo che un terzo degli elementi venga rimosso invece dello 0,1%.
for(int i=0; i<1000000;i++) arr[i]=rand()%3;// 1000; //генерируем исходный массив случайными значениями от 0 до 1000int Value=rand()%3; // 1000; // значение, которое нужно удалить из массива
Ecco come è andata a finire:
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Pastushak: Checksum = 333586; elementi - 667421; tempo di esecuzione = 108521 microsecondi 2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Korotky: Checksum = 333586; elementi - 667421; tempo di esecuzione = 5525 microsecondi 2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Fedoseev: Checksum = 333586; elementi - 667421; tempo di esecuzione = 4879 microsecondi 2018.11.13 19:45:22.164 Del (GBPUSD.m,H1) variante Semko: Checksum = 333586; elementi - 667421; tempo di esecuzione = 14479 microsecondi 2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Pavlov: Checksum = 998744; elementi - 667421; tempo di esecuzione = 0 microsecondi 2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Nikitin: Checksum = 333586; elementi - 667421; tempo di esecuzione = 5759 microsecondi 2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Vladimir: Checksum = 333586; elementi - 667421; tempo di esecuzione = 1542 microsecondi
La variante di Pavlov aveva un errore, ho dovuto commentarlo.
Conclusione: calcolare gli indirizzi in una matrice con una distanza arbitraria tra i loro numeri è ancora peggio che elaborare elementi in una riga, in un dato passo, molto meno il passo 1, il compilatore può ottimizzarlo.
P.S. I compilatori Pascal e Delphi di Borland fanno in modo che a runtime la variabile del ciclo non abbia importanza (in memoria), è messa da qualche parte nei registri della CPU.
Speravo che qualcuno fosse interessato all'approccio DBMS e lo controllasse, non ho aspettato. Ho dovuto farlo io stesso.
Inserito ArrayDeleteValue.mq5 nel tuo checker, è due volte peggio del tuo. Ho pensato al motivo e ho sistemato due righe in modo che un terzo degli elementi venga cancellato invece dello 0,1%.
Ecco come è andata a finire:
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Pastushak: Checksum = 333586; elementi - 667421; tempo di esecuzione = 108521 microsecondi 2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Korotky: Checksum = 333586; elementi - 667421; tempo di esecuzione = 5525 microsecondi 2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Fedoseev: Checksum = 333586; elementi - 667421; tempo di esecuzione = 4879 microsecondi 2018.11.13 19:45:22.164 Del (GBPUSD.m,H1) variante Semko: Checksum = 333586; elementi - 667421; tempo di esecuzione = 14479 microsecondi 2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Pavlov: Checksum = 998744; elementi - 667421; tempo di esecuzione = 0 microsecondi 2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Nikitin: Checksum = 333586; elementi - 667421; tempo di esecuzione = 5759 microsecondi 2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Vladimir: Checksum = 333586; elementi - 667421; tempo di esecuzione = 1542 microsecondi
La variante di Pavlov aveva un errore, ho dovuto commentarlo.
Conclusione: calcolare gli indirizzi in un array con una distanza arbitraria tra i loro numeri è ancora peggio che processare gli elementi in una riga in un determinato passo, tanto più che al passo 1 il compilatore può ottimizzarlo.
P.S. I compilatori Pascal e Delphi di Borland fanno in modo che a runtime la variabile del ciclo non abbia importanza (in memoria), è messa da qualche parte nei registri della CPU.
La versione di Pavlov è stata corretta. I vostri valori sono strani. Forse hai eseguito lo script dopo il profiling o il debugger senza ricompilare il codice? È così che funziona per me:
2018.11.1312:35:38.633 ArrayDeleteValue (EURUSD,D1) вариант Pastushak: Контрольная сумма = 496494849; элементов - 999011; время выполнения = 131964 микросекунд
2018.11.1312:35:38.636 ArrayDeleteValue (EURUSD,D1) вариант Korotky: Контрольная сумма = 496494849; элементов - 999011; время выполнения = 2310 микросекунд
2018.11.1312:35:38.639 ArrayDeleteValue (EURUSD,D1) вариант Fedoseev: Контрольная сумма = 496494849; элементов - 999011; время выполнения = 1834 микросекунд
2018.11.1312:35:38.641 ArrayDeleteValue (EURUSD,D1) вариант Semko: Контрольная сумма = 496494849; элементов - 999011; время выполнения = 773 микросекунд
2018.11.1312:35:38.645 ArrayDeleteValue (EURUSD,D1) вариант Pavlov: Контрольная сумма = 496494849; элементов - 999011; время выполнения = 2815 микросекунд
2018.11.1312:35:38.648 ArrayDeleteValue (EURUSD,D1) вариант Nikitin: Контрольная сумма = 496494849; элементов - 999011; время выполнения = 2475 микросекунд
2018.11.1312:35:38.653 ArrayDeleteValue (EURUSD,D1) вариант Vladimir: Контрольная сумма = 496656342; элементов - 999011; время выполнения = 3608 микросекунд
E nella vostra versione genera un checksum errato. E creare un array aggiuntivo non è di alcun beneficio, al contrario, rallenta il processo e consuma risorse aggiuntive.
In sostanza, tutti gli algoritmi sono uguali. Tutti modificano l'array elemento per elemento, e tutti si sforzano di ottenere la variante Fedoseev, perché non ha nulla di inutile. Solo che nel mio caso è fatto in blocchi usando ArrayCopy, quindi c'è un vantaggio di velocità.
Non so cosa sia mt4, non funziona nemmeno su win10, penso che sia una buona cosa
Ho modificato l'array.
Ho dovuto usare ArrayCopy , perchéMQL5 giurava che l'array fosse statico.

Se è una gara di velocità, offrirò la mia variante...
La tua variante è effettivamente la più veloce, ma contiene un bug: se tutti gli elementi di un array sono uguali a un filtro, la tua funzione uscirà dall'array.
Offrirò la mia variante, è un po' più lenta della tua:
2018.11.13 17:16:38.618 massiv v1 (EURUSD,M1) test my=1512090
2018.11.13 17:16:40.083 massiv v1 (EURUSD,M1) test alien=1464941
Sono diversi anni che fai questo tipo di domande. Hai imparato molto? Scusate, ma è evidente che siete ancora al livello dei byte e degli array elementari.
La domanda stessa è formulata in modo scorretto. Il compito non è quello di rimuovere i valori ripetuti (compito del livello GCE) ma in qualcosa di molto più grande, è necessario aggiornare la lista degli elementi validi. Se è così, la domanda dovrebbe suonare completamente diversa. Confondete e ingannate i partecipanti e, prima di tutto, voi stessi: imponete ai partecipanti una soluzione sbagliata in linea di principio e chiedete di renderla efficace.
Non faccio programmazione per il gusto di programmare, non ho l'obiettivo di diventare un mega-programmatore e di essere intelligente sui forum.
Cosa non capite nella domanda: cancellare un array di elementi definiti?
La tua variante è effettivamente la più veloce, ma contiene un bug: se tutti gli elementi di un array sono uguali a un filtro, la tua funzione uscirà dall'array.
Ti suggerisco la mia variante, è un po' più lenta della tua:
2018.11.13 17:16:38.618 massiv v1 (EURUSD,M1) test my=1512090
2018.11.13 17:16:40.083 massiv v1 (EURUSD,M1) test alien=1464941
Sì, grazie. Corretto.
Solo che anche voi avete un errore da qualche parte, perché il checksum non coincide perché manca un elemento da qualche parte. Non ha funzionato dove.
Modificato rimuovendo i passaggi non necessari
In entrambi i casi, ogni elemento viene trascinato al massimo una volta.
Speravo che qualcuno fosse interessato all'approccio DBMS e lo controllasse, non ho aspettato. Ho dovuto farlo io stesso.
Inserito ArrayDeleteValue.mq5 nel tuo checker, è due volte peggio del tuo. Ho pensato al motivo e ho sistemato due righe in modo che un terzo degli elementi venga rimosso invece dello 0,1%.
Ecco come è andata a finire:
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Pastushak: Checksum = 333586; elementi - 667421; tempo di esecuzione = 108521 microsecondi
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Korotky: Checksum = 333586; elementi - 667421; tempo di esecuzione = 5525 microsecondi
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Fedoseev: Checksum = 333586; elementi - 667421; tempo di esecuzione = 4879 microsecondi
2018.11.13 19:45:22.164 Del (GBPUSD.m,H1) variante Semko: Checksum = 333586; elementi - 667421; tempo di esecuzione = 14479 microsecondi
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Pavlov: Checksum = 998744; elementi - 667421; tempo di esecuzione = 0 microsecondi
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Nikitin: Checksum = 333586; elementi - 667421; tempo di esecuzione = 5759 microsecondi
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Vladimir: Checksum = 333586; elementi - 667421; tempo di esecuzione = 1542 microsecondi
La variante di Pavlov aveva un errore, ho dovuto commentarlo.
Conclusione: calcolare gli indirizzi in una matrice con una distanza arbitraria tra i loro numeri è ancora peggio che elaborare elementi in una riga, in un dato passo, molto meno il passo 1, il compilatore può ottimizzarlo.
P.S. I compilatori Pascal e Delphi di Borland fanno in modo che a runtime la variabile del ciclo non abbia importanza (in memoria), è messa da qualche parte nei registri della CPU.
Speravo che qualcuno fosse interessato all'approccio DBMS e lo controllasse, non ho aspettato. Ho dovuto farlo io stesso.
Inserito ArrayDeleteValue.mq5 nel tuo checker, è due volte peggio del tuo. Ho pensato al motivo e ho sistemato due righe in modo che un terzo degli elementi venga cancellato invece dello 0,1%.
Ecco come è andata a finire:
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Pastushak: Checksum = 333586; elementi - 667421; tempo di esecuzione = 108521 microsecondi
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Korotky: Checksum = 333586; elementi - 667421; tempo di esecuzione = 5525 microsecondi
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Fedoseev: Checksum = 333586; elementi - 667421; tempo di esecuzione = 4879 microsecondi
2018.11.13 19:45:22.164 Del (GBPUSD.m,H1) variante Semko: Checksum = 333586; elementi - 667421; tempo di esecuzione = 14479 microsecondi
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Pavlov: Checksum = 998744; elementi - 667421; tempo di esecuzione = 0 microsecondi
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Nikitin: Checksum = 333586; elementi - 667421; tempo di esecuzione = 5759 microsecondi
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Vladimir: Checksum = 333586; elementi - 667421; tempo di esecuzione = 1542 microsecondi
La variante di Pavlov aveva un errore, ho dovuto commentarlo.
Conclusione: calcolare gli indirizzi in un array con una distanza arbitraria tra i loro numeri è ancora peggio che processare gli elementi in una riga in un determinato passo, tanto più che al passo 1 il compilatore può ottimizzarlo.
P.S. I compilatori Pascal e Delphi di Borland fanno in modo che a runtime la variabile del ciclo non abbia importanza (in memoria), è messa da qualche parte nei registri della CPU.
La versione di Pavlov è stata corretta.
I vostri valori sono strani. Forse hai eseguito lo script dopo il profiling o il debugger senza ricompilare il codice?
È così che funziona per me:
E nella vostra versione genera un checksum errato. E creare un array aggiuntivo non è di alcun beneficio, al contrario, rallenta il processo e consuma risorse aggiuntive.
Solo che nel mio caso è fatto in blocchi usando ArrayCopy, quindi c'è un vantaggio di velocità.