説明#
例 1:
入力: 123
出力: 321
例 2:
入力: -123
出力: -321
例 3:
入力: 120
出力: 21
注意:
32 ビットの符号付き整数しか保存できない環境を想定しているため、値の範囲は [−231, 231 − 1] です。この仮定に基づいて、反転後に整数がオーバーフローする場合は、0 を返します。
アプローチ#
- 正負の符号を抽出する
- 正数に変換して各桁の数値を抽出する
- 抽出した数値を逆順に足し合わせる
- オーバーフローの判定
int reverse(int x){
char sign = 1,nums = 0,value[10] = {0};
int final = 0;
long final_long = 0;
//符号の抽出と数値の抽出
if(x < 0) {
if(x == -2147483648)//-2^31、オーバーフローで正数に変換できず、かつ反転後にオーバーフローする場合
return 0;
else
x = -x;
sign = -1;
}
//xの桁数を取得
for(;x;nums++) {
value[nums] = x % 10;
x = x / 10;
}
for(int i=0;nums > 0;nums--) {
final_long += value[i++];
if(nums > 1)//次の桁がある場合
final_long *= 10;
}
final = (int)final_long;
if(final == final_long)
return final * sign;
else
return 0;
}
注意#
- エラーチェックは、有効な正数に変換できるかどうかと、反転後にオーバーフローが発生するかどうかを確認する必要があります
------------------------------------------- 分割線!!!!-------------------------------------------------------
更新#
他の人の解法をインターネットで見て、非常にシンプルになることに気づきました。以下にコードを示します:
int reverse(int x){
int final = 0;
long final_long = 0;
while(x) {
final_long = final_long * 10 + x % 10;
x = x / 10;
}
final = (int)final_long;
if(final == final_long)
return final;
else
return 0;
}
- 元の符号の抽出は実際には必要ありません。正数と負数の計算中、唯一の違いは最後の余りの一桁を取るとき、負数の場合は符号付きで取得されることです。そのため、そのまま計算すれば良いです。自分は思考が固定化されていて、余計なことを考えていました。
- 最終結果の計算と余りの取得を同時に行うことができます。以前は整数の桁数を取得する必要があると思っていましたが、上記のように一度余りを取ってから ×10 すれば良いです。本当に簡略化されました。
- 直接比較しない限り、自分の固定化された思考では学ぶことができないことが本当にわかりました。この問題は無駄にならず、たくさんのことを学びました。