0

値の一部に依存するint値のリストを返す関数があります。

private List<int> GetColumn(int total, int column)
{
    List<int> retList = new List<int>();

    if (total <= 0)
    {
        return retList;
    }

    if (column < 0 || column > 2)
    {
        column = 0;
    }

    int pageSize = total / 3;

    int startIndex = column * pageSize;
    int endIndex = column * pageSize + pageSize;

    if (endIndex > total)
    {
        endIndex = total;
    }

    for (int i = startIndex; i < endIndex; i++)
    {
        retList.Add(i);
    }

    return retList;

}

ただし、次の理由で正しく機能しません:GetColumn(17、0)


[0,1,2,3,4]を返しますが、GetColumn( 17、1)の場合は[0,1,2,3,4,5]を返す必要があります-[6,7,8,9,10,11 ]
GetColumn(17、2)の場合-[12,13,14,15,16]

16の場合は次を返す必要があります:GetColumn(16、0)の場合-[0,1,2,3,4,5] for GetColumn(
16、1)-[6,7,8,9,10]
for GetColumn(16 、2)-[11,12,13,14,15]

関数で何を変更する必要がありますか?ありがとう!

4

3 に答える 3

3

これが必要な場合(数値は列ごとに増加しますが、行を最初に入力する必要があります):

for 16:
0  6  11
1  7  12
2  8  13
3  9  14
4  10 15
5

for 17:
0  6  12
1  7  13
2  8  14
3  9  15
4  10 16
5  11

どの列が余りを取得しているかを定義する必要があります。

int remainder = total % 3;

余りが1の場合、最初の列のみが6要素です。余りが2の場合、1列目と2列目は6要素です。これに従ってstartIndexとendIndexを計算する必要があります。

それで;

int pageSize = total / 3;
int remainder = total % 3;

int startIndex = column * pageSize + min(column, remainder);
int endIndex = startIndex + pageSize + (remainder > column ? 1 : 0);

動作するはずです。私はそれをテストしました、それは3とは異なる行サイズで動作します。

これが私が数式を取得した方法です。テーブルを描画することは、そのようなアルゴリズムを分類するための良い習慣です。

r:Remainder、c:column、ps:pagesize(上記で計算)

StartingIndex:
.  |r:0 |r:1   |r:2
----------------------
c:0|0   |0     |0
----------------------
c:1|ps  |ps+1  |ps+1
----------------------
c:2|ps*2|ps*2+1|ps*2+2

行サイズ4のテーブルを拡張すると、パターンを確認できます。

StartingIndex:
.  |r:0 |r:1   |r:2   |r:3
------------------------------
c:0|0   |0     |0     |0
------------------------------
c:1|ps  |ps+1  |ps+1  |ps+1
------------------------------
c:2|ps*2|ps*2+1|ps*2+2|ps*2+2
------------------------------
c:3|ps*3|ps*3+1|ps*3+2|ps*3+3

追加する値は、関連する列と余りの最小値です

同様に、endIndexの場合、指定された剰余と列のテーブルを作成すると、目的の列の長さがわかります。ここでテーブルを描くのに時間がかかりすぎて、あなたはすでにアイデアを持っていると思うので、今のところそれを書きません。

于 2012-03-09T07:32:17.000 に答える
0

整数の除算はゼロに向かって丸められます。したがって、17/3=5および-17/3=-5
必要なのは、次の整数に丸めることだと思います。

int pageSize = (int)Math.Ceiling(total / 3d);
于 2012-03-09T07:09:43.373 に答える
0

私が正しく理解している場合、要件は次のとおりです。

If the number is 3n,   divide it in 3 groups of n,   n   and n   elements.
If the number is 3n+1, divide it in 3 groups of n+1, n   and n   elements.
If the number is 3n+2, divide it in 3 groups of n+1, n+1 and n   elements.

最善の方法は、コードでそれを明示的にし、「賢い」ロジックを避けることです。単純な分割は、要約すると次のようになります。

If the number is 3n, the divisions are:
     0 ..  n-1
     n .. 2n-1
    2n .. 3n-1
If the number is 3n+1, the divisions are:
     0 .. n
   n+1 .. 2n
  2n+1 .. 3n
If the number is 3n+2, the divisions are:
     0 .. n
   n+1 .. 2n+1
  2n+2 .. 3n+1

C#では、次のようになります。

public static List<int> Divide3Columns(int total, int column)
{
  int startIndex = 0;
  int endIndex = 0;
  int pageSize = total / 3;

  if (total % 3 == 0)
  {
    startIndex = column * pageSize;
    endIndex = (column + 1) * pageSize - 1;
  }

  if (total % 3 == 1)
  {
    if (column == 0)
    {
      startIndex = 0;
      endIndex = pageSize; //pageSize + 1 elements;
    }
    else
    {
      startIndex = column * pageSize + 1;
      endIndex = (column + 1) * pageSize;
    }
  }

  if (total % 3 == 2)
  {
    if (column == 2)
    {
      startIndex = 2 * pageSize + 2;
      endIndex = 3 * pageSize + 1; //same as total - 1;
    }
    else
    {
      startIndex = column * (pageSize + 1);
      endIndex = (column + 1) * pageSize + column;
    }
  }

  List<int> result = new List<int>();
  for (int i = startIndex; i <= endIndex; i++)
  {
    result.Add(i);
  }
  return result;
}

答えは、常に3列に分割し、3列のみに分割することを前提としています。数値が可変の場合、列を決定するロジックを一般化できます。

于 2012-03-09T07:46:01.410 に答える