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.