web-dev-qa-db-ja.com

文字列をキャストせずに整数の桁を数えるにはどうすればよいですか?

この質問には単純明快な答えがあるのではないかと心配しています。アイテムのカウントの幅が何桁かを確認する必要があります。これにより、各アイテム番号に最小数の先行ゼロを配置して、配置を維持できます。たとえば、合計が10未満の場合は先行ゼロは必要ありません。10から99の間の場合は1になります。

1つの解決策は、アイテム数を文字列にキャストしてから文字数を数えることです。おい!もっと良い方法はありますか?

編集: 常用対数 を使用することは考えていなかったでしょう(そのようなものが存在することを知りませんでした)。だから、明白ではありません-私には-しかし、間違いなく簡単です。

33
Metaphile

これはそれを行うはずです:

int length = (number ==0) ? 1 : (int)Math.log10(number) + 1;
51
int length = (int)Math.Log10(Math.Abs(number)) + 1;

負の符号を考慮する必要がある場合があります。

12
Ryan Emerle

乗算を伴うステートメントが繰り返される場合、繰り返し除算よりも効率的なソリューションが繰り返されます... (nは桁数が必要な数値です)

unsigned int test = 1;
unsigned int digits = 0;
while (n >= test)
{
  ++digits;
  test *= 10;
}

アイテム数にある程度の上限がある場合(たとえば、unsigned intの32ビット範囲)、さらに良い方法は、いくつかの静的配列のメンバーと比較することです。

// this covers the whole range of 32-bit unsigned values
const unsigned int test[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };

unsigned int digits = 10;
while(n < test[digits]) --digits;
12
jheriko

Whileループを使用できます。これは整数演算のみを使用するため、対数よりも高速になる可能性があります。

int len = 0;
while (n > 0) {
    len++;
    n /= 10;
}

読者がこのアルゴリズムを調整してゼロと負の数を処理するようにすることは、練習問題として残しておきます。

4
Greg Hewgill

.Netで数値を埋め込む場合は、

num.ToString().PadLeft(10, '0') 

あなたが望むことをするかもしれません。

4
cjk

私はコメントを投稿したでしょうが、私の担当者のスコアは私にその区別を与えません。

私が指摘したかったのは、Log(10)は非常にエレガントな(読み取り:コード行が非常に少ない)ソリューションであるにもかかわらず、おそらくプロセッサに最も負担がかかるものであることです。

私はジェリコの答えがおそらく最も効率的な解決策であると思うので、そのように報われるべきです。

特に、これを多数の数値に対して行う場合は、.

2
user67143

数値には先行ゼロがないため、とにかく変換​​してそれらを追加します。とにかく最終結果が文字列でなければならないときに、長さを見つけるのを避けるために一生懸命努力している理由がわかりません。

1
Ken White

1つのソリューションは、10を底とする対数で提供されますが、これは少しやりすぎです。

0
mouviciel

ループして10回削除できます。ループする回数を数えます。

int num = 423;
int minimum = 1;
while (num > 10) {
    num = num/10;
    minimum++;
}
0
achinda99

わかりません、抵抗できません:/=を使用してください:

#include <stdio.h>

int
main(){
        int num = 423;
        int count = 1;
        while( num /= 10)
                count ++;
        printf("Count: %d\n", count);
        return 0;
}
534 $ gcc count.c && ./a.out
Count: 3
535 $ 
0
Charlie Martin