2017-04-06 17 views
4

開始値と終了値に基づいて特定の数の値所有者に値を分配しようとしています。バリューホルダーの数がの差よりも小さい場合開始値と終了値と値所有者の数に基づいて値を分配する

Start Value : 1 
End Value : 10 
Value Holders: 10 
| 
Expected Result: 1 2 3 4 5 6 7 8 9 10 

バリューホルダーの数は、開始値と終了値の差に等しい場合

は、それだけで単純な反復処理になります開始値と終了値、いくつかの数値をスキップする必要があります。目標は可能な限り均等に値を分配しようとすることです。

注:左/右のいずれかに寄りかかっは重要ではありません:)

Start Value : 1 
End Value : 10 
Value Holders: 5 
| 
Expected Result: 1 3 5 8 10 
       or 
       1 3 6 8 10 

Start Value : 1 
End Value : 10 
Value Holders: 3 
| 
Expected Result: 1 5 10 
       or 
       1 6 10 

バリューホルダーの数は、我々はいくつかの数字を開始値と終了値の差よりも多くの繰り返しされますされている場合。

Start Value : 1 
End Value : 10 
Value Holders: 15 
| 
Expected Result: 1 2 3 4 4 5 5 6 6 7 7 8 8 9 10 
       (or something similar) 

これをC#でどのように実装できますか?

答えて

4

それはちょうど別の宣言a1arithmetic progressionとの製剤(開始値)、N(値保持部の数)とaN(終了値)です。算術進行の式から


enter image description here

、我々は他のすべての値を知っているので、私たちはdを抽出することができます。

d = (aN - a1)/(N - 1) 

あなたはすべての値を知っているとき、あなたは、単に全体の等差数列のシーケンスを生成することができます

public int[] GetValues(int a, int b, int count) 
{ 
    double d = (b - a)/(double)(count - 1); 

    return Enumerable.Range(0, count) 
     .Select(i => (int)Math.Round(a + d * i)) 
     .ToArray(); 
} 

// Usage: 
int[] r1 = GetValues(1, 10, 10); // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 
int[] r2 = GetValues(1, 10, 5); // 1, 3, 6, 8, 10 
int[] r3 = GetValues(1, 10, 15); // 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10 

あなたは、二重のように中間結果を見るために(int)Math.Round()を削除することができます。

+0

これは私が探していたものです!どうもありがとう! :D –

2

開始点と終了点を「アンカー」として扱う - これらは常に分散シーケンスの最初と最後の要素を構成します。次に、それらの間の範囲(end-start)を数字間の「スペース」の数に分割します(holders - 1)。結果のstepの値は、分散されたシーケンスの連続する要素の間に追加する量です。

static List<int> Distribute(int start, int end, int holders) 
{ 
    List<int> result = new List<int>(); 

    // First value will always be the start 
    result.Add(start); 

    // Calculate the step size for the middle values 
    double range = end - start; 
    double step = range/(holders - 1); 

    // Generate the middle values using the step spacing 
    for (int i = 1; i < holders - 1; i++) 
    { 
     double target = step * i + start; 
     result.Add((int)Math.Round(target)); 
    } 

    // Last value is the end 
    result.Add(end); 
    return result; 
} 

丸めの方法によって、シーケンスが「傾く」方法が制御されます。 Math.Roundを使用すると、シーケンスが範囲の中心を中心に対称になります。 Math.Ceilingは、シーケンスを右に傾け、Math.Floorはシーケンスを左に傾けます。

+0

ありがとう!あなたの答えはうまくいきましたが、残念ながら答えとして1つ以上の投稿をタグ付けすることはできません。希望は大丈夫です。 :) –

関連する問題