To run embedded in a website, add the following html:
<script src="//onlinegdb.com/embed/js/ByP5zKVCZ"></script>
// NOTE: For the sake of practice, STL/stdlib helpers are not used, just std::string for memory management. | |
#include <string> | |
using std::string; | |
// Convert arbitrary base to base 10 | |
// - Input must be valid number in the given base | |
// - Base must be between 2 and 36 | |
// - If input or base are invalid, returns 0 | |
long ConvertTo10(const string& input, int base) | |
{ | |
if(base < 2 || base > 36) | |
return 0; | |
bool isNegative = (input[0] == '-'); | |
int startIndex = input.length()-1; | |
int endIndex = isNegative ? 1 : 0; | |
long value = 0; | |
int digitValue = 1; | |
for(int i = startIndex; i >= endIndex; --i) | |
{ | |
char c = input[i]; | |
// Uppercase it - NOTE: could be done with std::toupper | |
if(c >= 'a' && c <= 'z') | |
c -= ('a' - 'A'); | |
// Convert char to int value - NOTE: could be done with std::atoi | |
// 0-9 | |
if(c >= '0' && c <= '9') | |
c -= '0'; | |
// A-Z | |
else | |
c = c - 'A' + 10; | |
if(c >= base) | |
return 0; | |
// Get the base 10 value of this digit | |
value += c * digitValue; | |
// Each digit has value base^digit position - NOTE: this avoids pow | |
digitValue *= base; | |
} | |
if(isNegative) | |
value *= -1; | |
return value; | |
} | |
// Convert base 10 to arbitrary base | |
// - Base must be between 2 and 36 | |
// - If base is invalid, returns "0" | |
// - NOTE: this whole function could be done with itoa | |
string ConvertFrom10(long value, int base) | |
{ | |
if(base < 2 || base > 36) | |
return "0"; | |
bool isNegative = (value < 0); | |
if(isNegative) | |
value *= -1; | |
// NOTE: it's probably possible to reserve string based on value | |
string output; | |
do | |
{ | |
char digit = value % base; | |
// Convert to appropriate base character | |
// 0-9 | |
if(digit < 10) | |
digit += '0'; | |
// A-Z | |
else | |
digit = digit + 'A' - 10; | |
// Append digit to string (in reverse order) | |
output += digit; | |
value /= base; | |
} while (value > 0); | |
if(isNegative) | |
output += '-'; | |
// Reverse the string - NOTE: could be done with std::reverse | |
int len = output.size() - 1; | |
for(int i = 0; i < len; ++i) | |
{ | |
// Swap characters - NOTE: Could be done with std::swap | |
char temp = output[i]; | |
output[i] = output[len-i]; | |
output[len-i] = temp; | |
} | |
return output; | |
} | |
// Convert from one base to another | |
string ConvertBase(const string& input, int baseFrom, int baseTo) | |
{ | |
// NOTE: There is probably a more efficient way to convert between two bases. | |
// This however is easy to understand and debug. | |
return ConvertFrom10(ConvertTo10(input, baseFrom), baseTo); | |
} |
#include <iostream> | |
using std::cout; | |
using std::endl; | |
int main() | |
{ | |
// Bases 10 and 2 (positive) | |
cout << "===== 1 =====" << endl; | |
cout << ConvertBase("101", 2, 10) << endl; // 100(2) = 5(10) | |
cout << ConvertBase("5", 10, 2) << endl; // 5(10) = 101(2) | |
// Bases 10 and 16 (negative) | |
cout << "===== 2 =====" << endl; | |
cout << ConvertBase("-1A", 16, 10) << endl; // -1A(16) = -26(10) | |
cout << ConvertBase("-26", 10, 16) << endl; // -26(10) = -1A(16) | |
// Bases 5 and 7 | |
cout << "===== 3.1 =====" << endl; | |
cout << ConvertBase("100", 5, 10) << endl; // 100(5) = 25(10) | |
cout << ConvertBase("25", 10, 7) << endl; // 25(10) = 34(7) | |
// So therefore... | |
cout << "===== 3.2 =====" << endl; | |
cout << ConvertBase("100", 5, 7) << endl; // 100(5) = 34(7) | |
cout << ConvertBase("34", 7, 5) << endl; // 34(7) = 100(5) | |
// Larger Bases (26, 13) | |
cout << "===== 4 =====" << endl; | |
cout << ConvertBase("1234", 26, 13) << endl; // 1234(26) = 8864(13) | |
cout << ConvertBase("8864", 13, 26) << endl; // 8864(13) = 1234(26) | |
return 0; | |
} |
To run embedded in a website, add the following html:
<script src="//onlinegdb.com/embed/js/ByP5zKVCZ"></script>
I actually don't recommend doing this.
output = digit + output;
and even
output = output + digit;
Are both significantly slower operations than
output += digit;
when it comes to the std string data type.
Meanwhile, std:reverse is actually extremely performant.
So it's ultimately faster to build strings in reverse order using += and then reverse them using std::reverse.