数値を逆にする効率的なアルゴリズムを探しています。
入力: 3456789
出力: 9876543
C++ には、シフトとビット マスクのオプションがたくさんありますが、最も効率的な方法は何でしょうか?
私のプラットフォーム: x86_64
数字の範囲: XXX - XXXXXXXXXX (3 - 9 桁)
編集 私の入力の最後の桁は決してゼロにならないので、先行ゼロの問題はありません。
数値を逆にする効率的なアルゴリズムを探しています。
入力: 3456789
出力: 9876543
C++ には、シフトとビット マスクのオプションがたくさんありますが、最も効率的な方法は何でしょうか?
私のプラットフォーム: x86_64
数字の範囲: XXX - XXXXXXXXXX (3 - 9 桁)
編集 私の入力の最後の桁は決してゼロにならないので、先行ゼロの問題はありません。
このようなものが動作します:
#include <iostream>
int main()
{
long in = 3456789;
long out = 0;
while(in)
{
out *= 10;
out += in % 10;
in /= 10;
}
std::cout << out << std::endl;
return 0;
}
数値を文字列に変換してから、STL アルゴリズムを使用して文字列を逆にすることができます。以下のコードは動作するはずです:
long number = 123456789;
stringstream ss;
ss << number;
string numberToStr = ss.str();
std::reverse(numberToStr.begin(), numberToStr.end());
cout << atol(numberToStr.c_str());
これらの関連するヘッダー ファイルを含める必要がある場合があります。それが最も効率的な方法かどうかはわかりませんが、STL アルゴリズムは一般的に非常に効率的です。
#include <stdio.h>
unsigned int reverse(unsigned int val)
{
unsigned int retval = 0;
while( val > 0)
{
retval = 10*retval + val%10;
val /= 10;
}
printf("returning - %d", retval);
return retval;
}
int main()
{
reverse(123);
}
このソリューションはそれほど効率的ではありませんが、問題を解決し、役立つ可能性があります。符号付き整数 (int、long、long long など) の場合は long long を返し、符号なし整数 (unsigned int、unsigned long、unsigned long long など) の場合は unsigned long long を返します。
コンパイラの実装に依存する char 型は、符号付きまたは符号なしにすることができます。
#include <iostream>
#include <string>
#include <algorithm>
template <bool B>
struct SignedNumber
{
};
template <>
struct SignedNumber<true>
{
typedef long long type;
};
template <>
struct SignedNumber<false>
{
typedef unsigned long long type;
};
template <typename TNumber = int,
typename TResult = typename SignedNumber<std::is_signed<TNumber>::value>::type,
typename = typename std::void_t<std::enable_if_t<std::numeric_limits<TNumber>::is_integer>>>
TResult ReverseNumber(TNumber value)
{
bool isSigned = std::is_signed_v<TNumber>;
int sign = 1;
if (value < 0)
{
value *= -1;
sign = -1;
}
std::string str = std::to_string(value);
std::reverse(str.begin(), str.end());
return isSigned ? std::stoll(str) * sign : std::stoull(str) * sign;
}
int main()
{
std::cout << ReverseNumber(true) << std::endl; //bool -> unsigned long long
std::cout << ReverseNumber(false) << std::endl; //bool -> unsigned long long
std::cout << ReverseNumber('@') << std::endl; //char -> long long or unsigned long long
std::cout << ReverseNumber(46) << std::endl; //int -> long long
std::cout << ReverseNumber(-46) << std::endl; //int -> long long
std::cout << ReverseNumber(46U) << std::endl; //unsigned int -> unsigned long long
std::cout << ReverseNumber(46L) << std::endl; //long -> long long
std::cout << ReverseNumber(-46LL) << std::endl; //long long -> long long
std::cout << ReverseNumber(46UL) << std::endl; //unsigned long -> unsigned long long
std::cout << ReverseNumber(4600ULL) << std::endl; //unsigned long long -> unsigned long long
}
出力
1
0
64
64
-64
64
64
-64
64
64
このコードをテストします
https://repl.it/@JomaCorpFX/IntegerToStr#main.cpp