2つの配列があります
Array1 {5,6,7,8}
と
Array2 {2,1,1,0}
ある条件を満たすパターンはこちら
8,6,5,7
条件: Array2 のそれぞれの要素から Array1 の 8 までのパターンを考慮すると、パターンの左側に 8 より大きい 0 の要素があることを示しています。などなど……。
2 つの配列が与えられた場合、パターンを生成する方法があります。任意のアルゴリズム ロジックがあれば幸いです。
動作するはずのアルゴリズムは次のとおりです。
n
に、左に大きな数字が必要なため、左n+1
から 3 番目の空きスロットに配置します。これがあなたの例でどのように機能するかです:
_ _ 5 _
_ 6 5 _
_ 6 5 7
8 6 5 7
C# での大まかな実装を次に示します。
public static int[] algorithm(int[] numbers, int[] counts)
{
var pairs = numbers // EDIT:
.Zip(counts, (n, c) => new { n, c }) // This is needed to
.OrderBy(p => p.n) // correctly handle
.ThenBy(p => p.c) // duplicate numbers
.ToArray();
int[] output = new int[pairs.Length];
List<int> freeIndices = Enumerable.Range(0, pairs.Length).ToList();
for (int i = 0; i < pairs.Length; i++)
{
if (pairs[i].c < freeIndices.Count)
{
int outputIndex = freeIndices[pairs[i].c];
freeIndices.RemoveAt(pairs[i].c);
output[outputIndex] = pairs[i].n;
}
else
{
throw new ArgumentException();
}
}
return output;
}
編集:元のコードは重複した番号を正しく処理しませんでした。このバージョンではそうする必要があります。
これを 2 つの配列と考えるのではなく、Number/LeftCount ペアの 1 つのリストと考えたいと思います。
最初に (LeftCount == 0) のペアのセットのみを考えます。このセットのうち、番号が最も小さいもの ( n
) を選択します。
画面に書き込みn
ます。
このペアをリストから削除します。
Number より小さい残りのすべてのペアについてn
、LeftCount をデクリメントします。
リストに残っているペアがなくなるまで繰り返します。
このアルゴリズムの考え方を理解していれば、それを 2 つの別個の配列としてコーディングすることはそれほど難しくありません。