372

特に、C# や Java などの言語を使用する場合に、ページネーション コントロールを表示する方法を考えています。

1 ページあたりy個のチャンクで表示したいアイテムがx個ある場合、何ページ必要になりますか?

4

17 に答える 17

540

エレガントなソリューションを見つけました:

int pageCount = (records + recordsPerPage - 1) / recordsPerPage;

出典: Number Conversion、Roland Backhouse、2001 年

于 2008-08-20T13:42:08.257 に答える
221

浮動小数点への変換とその逆は、CPU レベルでは膨大な時間の無駄に思えます。

イアン・ネルソンの解決策:

int pageCount = (records + recordsPerPage - 1) / recordsPerPage;

次のように簡略化できます。

int pageCount = (records - 1) / recordsPerPage + 1;

AFAICS、これには Brandon DuRette が指摘したオーバーフロー バグはありません。一度しか使用しないため、構成ファイルから値をフェッチするための高価な関数からのものである場合、recordsPerPage を特別に保存する必要はありません。なにか。

つまり、config.fetch_value がデータベース ルックアップなどを使用している場合、これは非効率的である可能性があります。

int pageCount = (records + config.fetch_value('records per page') - 1) / config.fetch_value('records per page');

これにより、実際には必要のない変数が作成されます。これはおそらく(マイナーな)メモリへの影響があり、入力が多すぎます。

int recordsPerPage = config.fetch_value('records per page')
int pageCount = (records + recordsPerPage - 1) / recordsPerPage;

これはすべて 1 行で、データを 1 回だけフェッチします。

int pageCount = (records - 1) / config.fetch_value('records per page') + 1;
于 2009-02-02T13:26:00.953 に答える
94

C# の場合、解決策は値を double にキャストすることです (Math.Ceiling は double を取るため)。

int nPages = (int)Math.Ceiling((double)nItems / (double)nItemsPerPage);

Java では、Math.ceil() で同じことを行う必要があります。

于 2008-08-20T13:33:04.690 に答える
79

これにより、必要なものが得られるはずです。ページごとに x 個のアイテムを y 個のアイテムで割ったものが必ず必要になります。問題は偶数の場合です。そのため、部分的なページがある場合は、1 ページも追加したいと考えています。

int x = number_of_items;
int y = items_per_page;

// with out library
int pages = x/y + (x % y > 0 ? 1 : 0)

// with library
int pages = (int)Math.Ceiling((double)x / (double)y);
于 2008-08-20T13:31:08.797 に答える
18

Ian が提供した整数演算ソリューションは優れていますが、整数オーバーフローのバグに悩まされています。変数が all であると仮定すると、数学intを使用してバグを回避するようにソリューションを書き直すことができます。long

int pageCount = (-1L + records + recordsPerPage) / recordsPerPage;

recordsが の場合long、バグは残ります。モジュラス ソリューションにはバグがありません。

于 2008-09-18T21:01:13.327 に答える
8

分岐を回避するNick Berardi の回答の変形:

int q = records / recordsPerPage, r = records % recordsPerPage;
int pageCount = q - (-r >> (Integer.SIZE - 1));

注:(-r >> (Integer.SIZE - 1))の符号ビットで構成され、 32 回繰り返されます (演算子rの符号拡張のおかげです)。これは、がゼロまたは負の場合は 0、正の場合は -1 と評価されます。したがって、 からそれを引くと、if に 1 を加える効果があります。>>rrqrecords % recordsPerPage > 0

于 2011-05-04T13:00:24.223 に答える
7

拡張メソッドが必要な場合:

    public static int DivideUp(this int dividend, int divisor)
    {
        return (dividend + (divisor - 1)) / divisor;
    }

ここではチェックしません (オーバーフローDivideByZeroなど)。必要に応じて自由に追加してください。ところで、メソッド呼び出しのオーバーヘッドが心配な方のために説明すると、このような単純な関数はコンパイラによってインライン化される可能性があるので、そこは気にする必要はないと思います。乾杯。

PSこれも知っておくと便利かもしれません(残りは得られます):

    int remainder; 
    int result = Math.DivRem(dividend, divisor, out remainder);
于 2016-09-15T19:52:17.970 に答える
4

records == 0 の場合、rjmunro の解は 1 を返します。正しい解は 0 です。とはいえ、records > 0 であることがわかっている場合 (そして、recordsPerPage > 0 を想定していると確信している場合)、rjmunro の解は正しい結果を返し、オーバーフローの問題はありません。

int pageCount = 0;
if (records > 0)
{
    pageCount = (((records - 1) / recordsPerPage) + 1);
}
// no else required

すべての整数演算ソリューションは、どの浮動小数点ソリューションよりも効率的です。

于 2009-02-11T10:18:14.573 に答える
3

もう 1 つの方法は、mod() 関数 (または「%」) を使用することです。ゼロ以外の剰余がある場合は、除算の整数結果をインクリメントします。

于 2008-08-20T13:30:43.213 に答える
2

あなたが使用することができます

(int)Math.Ceiling(((decimal)model.RecordCount )/ ((decimal)4));
于 2021-10-07T10:16:40.887 に答える
0

ゼロのテストで分岐を削除する代わりの方法:

int pageCount = (records + recordsPerPage - 1) / recordsPerPage * (records != 0);

これがC#で機能するかどうかわからない場合は、C /C++で機能する必要があります。

于 2010-08-13T03:26:08.850 に答える
-1

結果を繰り返し処理できる一般的なメソッドが興味深い場合があります。

public static Object[][] chunk(Object[] src, int chunkSize) {

    int overflow = src.length%chunkSize;
    int numChunks = (src.length/chunkSize) + (overflow>0?1:0);
    Object[][] dest = new Object[numChunks][];      
    for (int i=0; i<numChunks; i++) {
        dest[i] = new Object[ (i<numChunks-1 || overflow==0) ? chunkSize : overflow ];
        System.arraycopy(src, i*chunkSize, dest[i], 0, dest[i].length); 
    }
    return dest;
}
于 2010-10-28T14:09:15.533 に答える
-2

以下は、上記のソリューションよりも丸めを行う必要がありますが、パフォーマンスが犠牲になります (0.5*rctDenominator の浮動小数点計算による)。

uint64_t integerDivide( const uint64_t& rctNumerator, const uint64_t& rctDenominator )
{
  // Ensure .5 upwards is rounded up (otherwise integer division just truncates - ie gives no remainder)
  return (rctDenominator == 0) ? 0 : (rctNumerator + (int)(0.5*rctDenominator)) / rctDenominator;
}
于 2013-02-07T15:02:34.733 に答える
-2

分を時間と分に変換する必要があるのと同様のニーズがありました。私が使用したのは:

int hrs = 0; int mins = 0;

float tm = totalmins;

if ( tm > 60 ) ( hrs = (int) (tm / 60);

mins = (int) (tm - (hrs * 60));

System.out.println("Total time in Hours & Minutes = " + hrs + ":" + mins);
于 2012-03-19T13:47:00.773 に答える
-4

浮動小数点除算を行ってから、ceiling 関数を使用して、値を次の整数に切り上げます。

于 2008-08-20T13:29:57.333 に答える