なら - ページ 6

 
Georgiy Merts:

どうだろう...

私見ですが、このような「空」のブロックも「無限ループ」(forでもwhileでも)も、計算しにくいエラーが発生する可能性がある危険なプログラミングスタイルだと思います。

ループの条件チェック演算子は無意味なものではなく、何らかの負担が必要です。 もし「無限ループ」があるとすれば、それはループの内部に何らかの追加出力や中断があり、それが必ずしも明らかでないことを意味します。ちなみに、私もbreak演算子は好きではなく、ループ内では必ずcontinue 演算子を使います。


そして、ここでも言われたように、コードの難読化は幼稚でしかない...。誰かが自分のコードを売ったり、他の方法で何百万ドルも手に入れることを恐れている偉大なプログラマー=コピー主義者がここに集まっている...プライドは大罪の一つだ!」。

は同意しない。
このコードを無限ループとブレークなしで書き換えてみてください。

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:

は納得いかない。
このコードを無限ループとブレークなしで書き換えてみてください。

面白い仕事ですね。

私見では、提示されたコードは、構造は明確であり、機能も有用であるが、むしろ「不透明」で理解しにくいものである。

一見すると、while (i<size) {...} のようなループになるはずですが、まだしっかり理解できていないのが現状です。

手に入れたらすぐに取りかかります。

 
Georgiy Merts:

面白い仕事ですね。

私見ですが、提示されたコードは、構造は明確で機能も有用なのですが、かなり「不透明」で理解しにくいです。

一見すると、while (i<size) {...} のようなループになるはずですが、まだ十分に理解できていないようです。

気が向いたら、すぐに取りかかります。

この関数は,配列 a[] からすべての値を削除し,データ列を変更せずに削除した要素から「穴」を取り除いてコンパクト化します.

 
Nikolai Semko:

この関数は,配列 a[] から全ての値を削除し,データの並びを変えずに削除した要素から「穴」を取り除いてコンパクト化します.

はい、そうです。目的は明確で、関数自体も便利です。 今はまだできませんが、後で仕組みを理解して、無限ループのないものに書き直します。さて、そして--私の書く関数の変種を、書きます。

 
Georgiy Merts:

そうそう、だから言ったじゃないですか、目的ははっきりしているし、関数自体も便利なんですよ。 今はまだ無理です、後で自分の仕事を整理して、無限ループのないものに書き直します。さて、それから--私バージョンの関数を、私なりに書いてみますね。

ここから 引用しています。1年半前に自然発生的な大会がありました。

 
Nikolai Semko:

は同意しない。
このコードを無限ループとブレークなしで書き換えてみてください。


/// навскидку, даже не проверял
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:


そうですね......もっとコンパクトなバリエーションがあるのは確かなのですが、速度が遅い。
あなたの variant は上記より 2-3 倍遅く、間違ったチェックサムを与えるので、 どこかでエラーがあります。
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 микросекунд
ファイル:
 
Georgiy Merts:

どうだろう...

私見ですが、このような「空」のブロックも「無限ループ」(forでもwhileでも)も、計算しにくいエラーが発生する可能性がある危険なプログラミングスタイルだと思います。

ループの条件チェック演算子は無意味なものではなく、何らかの負担が必要です。 もし「無限ループ」があるとすれば、それはループの内部に何らかの追加出力や中断があり、それが必ずしも明らかでないことを意味します。ちなみに、私もbreak演算子は好きではなく、ループ内では必ずcontinue 演算子を使います。


そして、ここでも言われたように、コードの難読化は幼稚でしかない...。誰かが自分のコードを売ったり、他の方法で何百万ドルも手に入れることを恐れている偉大なプログラマー=コピー主義者がここに集まっている...プライドは大罪の一つだ!」。

ああ...
 
Maxim Kuznetsov:


マキシム、そんなことはない、2サイクルあるはずだ、そうでなければ方法がないのだ。まず不要な要素を取り除き、次に配列を上方向に「縮める」(float)。 2つ目のループは、1つ目のループの内側にあります。

 

for構文では、条件をチェックし、サイクルが始まる前に終了させる。

while構文では、条件をチェックし、ループが終了する前に終了させます。

無限ループは、条件をチェックし、ループ内の任意の場所で終了することを意味します。