The Problem:
A company is distributing phone numbers to its employees to make things easier. the next digit cannot be equal to the last is the only rule for example 0223 is not allowed while 2023 is allowed. At least three digits will be excluded every time. Write a function that takes in a length of the phone number and the digits that will be excluded. The function should print all possible phone numbers.
I got this question in an interview and I have seen one like it before at my university. It is a permutation problem. My question is what is the best way or decent way to solve this without a million for loops.
I do understand that this is technically how it works
length of phone number = 3;
[0-9], [0-9] excluding the last digit, [0-9] excluding the last digit
but I am unsure on how the best way to turn this into code. Any language is accepted!
thank you:
Also I might be asking this in the wrong place. please let me know if I am.
A simple way to solve this problem could be using Recursion. Here's my commented C++ code:
void solve(int depth, int size, vector <int> &curr_seq){
// If the recursion depth is equal to size, that means we've decided size
// numbers, which means that curr_seq.size() == size. In other words, we've
// decided enough numbers at this point to create a complete phone number, so
// we print it and return.
if(depth == size){
for(int item : curr_seq){
cout << item;
}
cout << "\n";
return;
}
// Try appending every possible digit to the current phone number
for(int i = 0; i <= 9; ++i){
// Make sure to only append the digit i if it is not equal to the last digit
// of the phone number. We can also append it, however, if curr_seq
// is empty (because that means that we haven't decided the 1st digit yet).
if(curr_seq.empty() || curr[curr.size() - 1] != i){
curr_seq.push_back(i);
solve(depth + 1, size, curr);
curr_seq.pop_back();
}
}
}
I think I like the recursive solution, but you can also just generate all permutations up to the limit (iterate), filter out any with repeating digits, and print the successful candidates:
#include <iomanip>
#include <iostream>
#include <sstream>
using namespace std;
// Because C/C++ still has no integer power function.
int ipow(int base, int exp) {
int result = 1;
for (;;) {
if (exp & 1)
result *= base;
exp >>= 1;
if (!exp)
return result;
base *= base;
}
}
void noconsec(const int len) {
int lim = ipow(10, len);
// For e.g. len 4 (lim 10000),
// obviously 00xx won't work, so skip anything smaller than lim / 100.
int start = (len <= 2) ? 0 : (lim / 100);
for (int num = start;num < lim;num++) {
// Convert to string.
std::stringstream ss;
ss << std::setw(len) << std::setfill('0') << num;
std::string num_s = ss.str();
// Skip any consecutive digits.
bool is_okay = true;
auto prev_digit = num_s[0];
for (int digit_idx = 1;digit_idx < num_s.length();digit_idx++) {
auto digit = num_s[digit_idx];
if (prev_digit == digit) {
is_okay = false;
}
prev_digit = digit;
}
// Output result.
if (is_okay) {
cout << num_s << "\n";
}
}
}
int main(const int argc, const char * const argv[]) {
noconsec(4);
}
Differences to note, this needs an integer power function to compute the limit. Converting an int to a string and then checking the string is more complex than constructing the string directly. I guess it could be useful if you have a list of integers already, but mostly I did it for fun.
Related
The problem says that you have a string consisting of digits & special chars. All you have to do is to remove all the chars and divide the digits into blocks separated by '-'. The block holds 3 digits or 2 digits but cannot be 1 alone. For example:
input: "aasnd1df2d3dfg4gfd56f7gaad8ew9ds2sa1"
After the removal of the chars, it should be like "12345678921" and then it should be divided into blocks, so the final output would be like "123-456-789-21".
I made the char removal part, but I can't make the blocks division. Any ideas?
string removeNumbers(string str)
{
int current = 0;
string dig;
int len=0;
int ctr=0;
for(int i = 0; i < str.length(); i++){
if (isdigit(str[i])){
str[current] = str[i];
current++;
}
}
dig= str.substr(0,current);
return dig;
}
You first function works. However, it is a little bit too complicated and should be refactored. Also the name is wrong. It removes the NON-digits.
I will show a similar, but easier solution to you later in the code example.
Now the tricky part. You want to distribute the digits equally in a group with a given fixed size. I will explain the general approach with arbitrary group sizes to you.
Let us assume that you want to split an array of a given size into groups of a fixed size, here the array of digits (your string) into groups of size gs, in your example 3.
Then we can calculate the number of groups by a simple integer division. So, basically the number of elements in the array (number of digits in your string) devided by the group size. Since an integer division of a number by a group size will result in 0 for the first group-size elements, we will add an offset of one and get the simple formular:
const size_t numberOfResultingGroups = ((numberOfDigits-1) / groupSize) + 1 ;
This should be understandable. And how many elements will there be in one group? We can calculate this again with an integer division. So, number of elements (digits) divided by the group size. Also very straigtforward.
const size_t basicGoupSize = numberOfDigits / numberOfResultingGroups;
Also very easy to understand. But there may be a remainder as a result of the integer division. These remaining elements need also to be distributed.
We could calculate the remainder with a modulo division, but also in a classical way:
int digitsToDistribute = numberOfDigits - (numberOfResultingGroups * basicGoupSize);
Also this is simple to understand.
And note, the remainder (the digitsToDistribute) can of course never be bigger than the number of groups.
We can then in a loop use the "basicGoupSize" and add a 1 to it, as long as there are remaining "digitsToDistribute". So, in each loop run, we will check, if there are still remaining bytes to distribute, and, in case of yes, add 1 to the "basicGoupSize" and the decrement the "digitsToDistribute".
And so all bytes will be evenly distributed.
Next is the handling of a dash. Many people think of it like print something, then dash, then something, then dash, then something, then dash aso.
But the handling of the last dash may be difficult. And so, we turn the sequence around and print a dash, followed by something, followed by a dash, followed by something aso. And we simply suppress the first dash.
Everything together will lead us to the solution (This is one of many possible solutions):
#include <iostream>
#include <string>
// Remove all non-digits from a string
std::string removeNonDigits(const std::string &str)
{
std::string dig;
for (unsigned int i = 0; i < str.length(); i++) {
if (::isdigit(str[i])) {
dig += str[i];
}
}
return dig;
}
int main() {
// Ourtest string
std::string test{ "aasnd1df2d3dfg4gfd56f7gaad8ew9ds2sa1sdf34sdff56sdff78sdf" };
// Remove all non digits
std::string digits{ removeNonDigits(test) };
// Our group length will be 3 (can be anything else)
constexpr size_t groupSize{ 3u };
// How many digitsdowe haveinour test string
const size_t numberOfDigits = digits.length();
// Trivial case: Number of digits is smaller than the desired group size. Simply print it
if (numberOfDigits < groupSize) {
std::cout << digits << '\n';
}
else {
// Ok, now we want to build groups and distribute remainders
// How many goups will we have? Integer division by group size (corrected for a 1 offset)
const size_t numberOfResultingGroups{ ((numberOfDigits-1) / groupSize) + 1 };
// A basic group will have this size. Integer division of number Of digits by number of groups
const size_t basicGoupSize{ numberOfDigits / numberOfResultingGroups };
// Maybe not all digits are used up. This is the remainder.
// We will add 1 to the basic group size as long as there are remaining digits
int digitsToDistribute = numberOfDigits - (numberOfResultingGroups * basicGoupSize);
// Handling of dashes. We will notprint a dash in front of the FIRST group
bool printDashInFrontOfGroup = false;
// Start position of substring
size_t stringStartPos{};
// No print all groups
for (size_t i{}; i < numberOfResultingGroups; ++i) {
// Length of group. So base length + 1, as long as there are remaining digits to distribute
const size_t length = basicGoupSize + (((digitsToDistribute--) > 0) ? 1 : 0);
// Print dash and sub string
std::cout << (std::exchange(printDashInFrontOfGroup, true)?"-":"") << digits.substr(stringStartPos, length);
// And,next start position
stringStartPos += length;
}
}
return 0;
}
Edit
Some additional note:
All the above algorithm is deterministic. It will give the mathematical correct solution. Predictable. For different group sizes.
As a basic rule. Make your design, the mathematics and the algorithm before start coding. Then implement everything.
Example: Removing non digits from a string in C++ is a really very short one-liner:
// Remove all-non-digits
test = std::regex_replace(test, std::regex(R"([^0-9])"), "");
That is basically very simple and actually a no brainer. Anyway. People may do it differently, or more complicated. For whatever reason.
And as said, if you do your design before coding then you can come up with really compact solutions. One of many possible examples:
#include <iostream>
#include <string>
#include <regex>
#include <algorithm>
#include <vector>
#include <experimental/iterator>
auto splitToEqualParts(const std::string s, const size_t groupSize) {
std::vector<std::string> result{}; // Here we will store all the split string parts
int toDistribute = (int)s.size() - (((((int)s.size() - 1) / (int)groupSize) + 1) * (int)(s.size() / ((((int)s.size() - 1) / (int)groupSize) + 1)));
// Add all sub-string parts to result vector
for (size_t i{}, pos{}, length{}; i < (size_t)((((int)s.size() - 1) / (int)groupSize) + 1); ++i, pos += length) {
length = (s.size() / ((((int)s.size() - 1) / (int)groupSize) + 1)) + (toDistribute-- > 0) * 1;
result.push_back(s.substr(pos, length));
}
return result;
}
int main() {
// Some test string
std::string test{ "aasnd1df2d3dfg4gfd56f7gaad8ew9ds2sa1sdf34sdff56sdff78sdf" };
// Remove all-non-digits
test = std::regex_replace(test, std::regex(R"([^0-9])"), "");
// Split into equal parts
std::vector part{ splitToEqualParts(test, 3) };
std::copy(part.begin(), part.end(), std::experimental::make_ostream_joiner(std::cout, "-"));
return 0;
}
Compiled and tested with GCC and Clang. Using C++17.
Of course the common sub expressions maybe put in const variables. But basically no need. An optimizing compiler will do it for you.
The above will work for all group sizes (>0) and any number of digits in the string . . .
I suggest
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
string remove_chars(string & s)
{
string inter_result;
for_each(s.begin(), s.end(), [&inter_result](char c) { if (isdigit(c)) inter_result += c; });
size_t length = inter_result.length();
if (length <= 3)
{
return inter_result;
}
string result;
size_t pos = 0, step = 3;
while (pos < length)
{
if (length - pos - 3 == 1) step = 2;
if (result.length() > 0)
{
result += "-";
}
result += inter_result.substr(pos, step);
pos += step;
}
return result;
}
int main()
{
string s = "aasnd1df2d3dfg4gfd56f7gaad8ew9ds2sa1";
cout << remove_chars(s) << endl;
return 0;
}
How to obtain rightmost unset bit position of a number N in c++.
1<= N <= 2^60
storing as number does not work since 2^60 can only be stored in string.
thus following does not work
long long getBitUtil(long long n) {
return log2(n&-n)+1;
}
long long getBit(long long n) {
return getBitUtil(~n);
}
Try this. Code is self explanatory with comments
int getRightmostUnSetBit(string s, int pos)
{
int l= s.size();
int lc = s[l-1];
if(lc>=48 && lc<=57 && lc%2 ==0)
return pos; // if last digit is even return position
else
{// divide the number into half and call function again.
string s2 = "";
int rem =0;
for(int i =0; i<l;i++)
{
int d = s[i]-'0';
d = rem *10 + d;
int q = d/2;
rem = d%2;
s2.push_back('0'+q);
}
return getRightmostUnSetBit(s2,pos+1); //call for s2
}
}
Take input in string and call from main
int pos = getRightmostUnSetBit(s,1);// will not work if s is "0" or similar to "000...". So check for it before function calling.
For normal integers the solution is basically given in the book Hackers Delight. I can only refer to the book. I cannot copy. But section 2.1 gives already good hints.
Depending on your OS you will most likely have 64 bit data types. With 64 bit data types, you can still use arithmentic solutions for your given number range. Above that, you should use string representations.
Then we will convert a big decimal number given as string into a string containing its binary equivalent.
Then we search for the last 0 in the resulting binary string.
The secret is to do a division by 2 for a number given as string. This can be done as we learned in school on a piece of paper.
And then check, if the number is even or odd and put a 1 or 0 respectively in the resulting string.
This will work for abitrary big numbers. Limiting factor (but here not really) is the length of the resulting binary string. That must fit into a std::string :-)
See:
#include <string>
#include <iostream>
#include <bitset>
#include <iterator>
#include <regex>
#include <stack>
#include <algorithm>
// Odd numbers. We will find out, if a digit is odd or even
std::string oddNumbers{ "13579" };
// Devide a number in a string by 2. Just like in school on a piece of paper
void divideDecimalNumberAsStringBy2(std::string& str)
{
// Handling of overflow during devisions
unsigned int nextNumberToAdd{ 0 };
// The resulting new string
std::string newString{};
// Go through all digits, starting from the beginning
for (char& c : str) {
// Get overflow for next round
unsigned int numberToAdd = nextNumberToAdd;
// Get the overflow value for the next devision run. If number is odd, it will be 5
nextNumberToAdd = (oddNumbers.find(c) != std::string::npos) ? 5 : 0;
// Do the devision. Add overflow from last round
unsigned int newDigit = (c - '0') / 2 + numberToAdd;
// Build up newe string
newString += static_cast<char>(newDigit + '0');
}
// Remove leading zeroes
str = std::regex_replace(newString, std::regex("^0+"), "");
}
// Convert a string with a big decimal number to a string with a binar representation of the number
std::string convertDecimalStringToBinaryString(std::string& str)
{
// Resulting string
std::string binaryDigits{};
// Until the string is empty. Will be shorter and short because of devision by 2
while (!str.empty()) {
// For an even number we add 0, for an odd number we add 1
binaryDigits += (oddNumbers.find(str.back()) == std::string::npos) ? '0' : '1';
// And devide by 2
divideDecimalNumberAsStringBy2(str);
}
// Bits come in wrong order, so we need to revers it
std::reverse(binaryDigits.begin(), binaryDigits.end());
return binaryDigits;
}
int main()
{
// Initial string with a big number. Get input from user
std::string bigNumber{};
std::cout << "Enter big number: ";
std::cin >> bigNumber;
// Convert it
std::string binaryDigits = convertDecimalStringToBinaryString(bigNumber);
// Find the last 0
unsigned int posOfLast0 = binaryDigits.rfind('0');
// Show result
if (posOfLast0 == std::string::npos)
std::cout << "\nNo digit is 0 --> " << binaryDigits << '\n';
else
std::cout << "\nSize of resulting string: "<< binaryDigits.size() << "\nPos of last 0: " << posOfLast0+1 << "\nBinary String:\n\n" << binaryDigits << '\n';
return 0;
}
this is a super simple problem but it's late and I cant figure out for the life of me why this function doesnt work. I want it to print 1234, but instead it prints 123121. can someone explain what's going on and how to fix it? thanks
#include <iostream>
const int size = 20;
void set_int( int num )
{
int digits[size];
for ( int i = size - 1; i >= 0; i-- )
{
digits[i] = num % 10;
num /= 10;
if ( num != 0 )
std::cout << num;
}
}
int main()
{
set_int( 1234 );
return 0;
}
Well you are outputting the number instead of the digit.
Try changing like,
cout << digits[i]
Further clarification :
On the first run of the loop your num will be 1234 / 10 = 123
Next run your number will be 123 / 10 = 12
Next is going to be 1
You are outputing num, so you get 123121 .
There are several things wrong with that code.
Firstly, the definition
int digits[size];
is a variable length array, which is valid C (since the 1999 C standard) but is not valid C++. Unfortunately, some C++ compilers support such things as an extension.
Second, even if we assume that definition is valid, your code is essentially stating that you need an array with 1234 elements to hold integral values corresponding to four digits (1,2,3, and 4).
As MichaelCMS has described, your code is outputting something other than the digits too. A value of 1234 has 4 digits, so you would need to loop a total of 4 times to find all digits (if doing it right). You would not need to loop 1234 times.
MichaelCMS explained correctly, why you have such output. There are mistakes in your function. I wrote another one.
You can use next code, which helps to find digits of number.
#include <iostream>
int FindNumberOfDigits(int number);
void SplitNumberIntoDigits(int number);
// Splits number into digits.
// Works with not big numbers.
void SplitNumberIntoDigits(int number)
{
int size = FindNumberOfDigits(number);
int * digits = new int[size];
int divider = 0;
int degree = 0;
for(int digit = size; digit > 0; digit --)
{
// Find degree of divider
degree = digit;
// Find divider for each digit of number.
// For 1234 it will be 1000. For 234 it will be 100.
divider = pow(10, degree - 1);
// We use "abs" to get digits without "-".
// For example, when -1234 / 1000, you get -1.
digits[digit] = abs(number / divider);
// Cut number to find remaining digits.
number %= divider;
std::cout << digits[digit];
}
std::cout << std::endl;
}
// If number = 0, number of digits will be 1.
// Else returns number of digits.
int FindNumberOfDigits(int number)
{
int digitsNumber = 0;
if (number)
{
// calculates number of digits
while (number / 10)
{
number /= 10;
digitsNumber ++;
}
}
digitsNumber += 1;
return digitsNumber;
}
int _tmain(int argc, _TCHAR* argv[])
{
SplitNumberIntoDigits(1234);
SplitNumberIntoDigits(0);
SplitNumberIntoDigits(1);
SplitNumberIntoDigits(-1234);
SplitNumberIntoDigits(1234567890);
return 0;
}
As a result this code can help you to find digits of not big numbers. It works with positive, negative numbers and zero.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
How can I generate all combinations of n elements in groups of k?
For example, takig "abcd" in groups of 3, from [aaa] to [ddd]?
EDIT: What I've "accomplished" so far:
int main (int argc, char * argvc[]) {
int tComb = 0, array[7] = { 48 , 48 , 48 , 48 , 48 , 48 , 48 };
while ( tComb < atoi(argvc[1]) ) {
for (int i = 6 ; i>0 ; i--) {
if (array[i] == 58)
array[i] = 65;
if (array[i] == 91)
array[i] = 97;
if (array[i] == 123){
array[i] = 48;
array[i-1]++;
}
}
std::cout << "Current Combination: ";
std::cout << array;
std::cout << "\n";
tComb++;
array[6]++;
}
}
It'll try and generate backward the latest combination of alphanumeric characters, but it's hardcoded and won't work well.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
unsigned powu(unsigned base, unsigned exp){
unsigned result = 1;
while(exp > 0){
if(exp & 1)
result *= base;
base = base * base;
exp >>=1;
}
return result;
}
int main(int argc, char *argv[]){
if(argc != 3){
fprintf(stderr, "Usage : RepeatedPermutation abcd 3\n");
return -1;
}
char *list = argv[1];
unsigned gp_len = atoi(argv[2]);
unsigned list_len = strlen(list);
char *gp = calloc(gp_len+1, sizeof(char));
int total_n = powu(list_len, gp_len);
int i, j;
for(i=0;i<total_n;++i){
int n = i;
for(j=0;j<gp_len;++j){
gp[gp_len -j -1] = list[n % list_len];
n /= list_len;
}
printf("[%s]\n", gp);
}
free(gp);
return 0;
}
Am not sure but i think this is the answer to your question. If you want three groups than you should have 3 different loops.Its pretty simple when you see the output of this program.
You just need to increment the value of what ever you want to generate there possible combination.
The below Code will generate all possible combination of "abcd" in groups of 3, from [aaa] to [ddd].
int main()
{
char ch1;
char ch2;
char ch3;
for(ch1='a';ch1<='d';ch1++)
{
for(ch2='a';ch2<='d';ch2++)
{
for(ch3='a';ch3<='d';ch3++)
{
printf("%c %c %c\n",ch1,ch2,ch3);
}
printf("\n"); //just to have clean and understandable output
}
printf("\n\n\n"); //just to have clean and understandable output
}
return 0;
}
One method to generate all the combinations is to treat this as a number counting program.
The Counting Algorithm
Let's take the case of "digits": a, b, c, and d.
The first number is: aaaa. Much like decimal: 0000.
The second number is: aaab. Decimal: 0001.
The third number is: aaac, decimal: 0002.
The fourth number is: aaad, decimal: 0003.
This process is known as incrementing, e.g. adding a constant value each time.
Now comes the tricky part, incrementing the last digit. According to number counting rules, when the last digit is reached, the last digit is replaced by the first and the digit in the next column is replaced. This is equivalent of a decimal number incrementing from 09 to 10.
So in the example above, the next number in the sequence is: aaba.
This is known as carry, as you are carrying the overflow to the next digit.
Converting Algorithm to Code
Looks like there is a loop to count from first digit to last digit:
#define MAXIMUM_DIGIT_POSITIONS 4
const char FIRST_CHAR = 'a';
const char LAST_CHAR = 'd';
std::vector<char> number(MAXIMUM_DIGIT_POSITIONS); // Reserve some slots.
void Print_Number(const std::vector<char>& number);
int main(void)
{
// Initialize the number
int position = 0;
for (position = 0; position < MAXIMUM_DIGIT_POSITIONS; ++position)
{
number.push_back(FIRST_CHAR);
}
Print_Number(number);
// Loop: incrementing
position = MAXIMUM_DIGIT_POSITIONS - 1; // Because arrays are zero based indexing
while (number[position] < LAST_CHAR)
{
number[position] = number[position] + 1; // Increment to next digit, same position.
Print_Number(number);
}
// Pause before closing
std::cout << "Paused. Press ENTER to close.\n";
std::cin.ignore(100000, '\n');
return EXIT_SUCCESS;
}
void Print_Number(const std::vector<char>& number)
{
for (std::vector<char>::const_iter iter = number.begin();
iter != number.end();
++iter)
{
std::cout << *iter;
}
cout << "\n";
}
Handling Carry
The above program demonstrates counting in a single column. But how to handle the incrementing of the last digit?
Looks like we need to increment the digit in the previous position.
Looking ahead, the value in the previous column will be incremented, until it too, needs to be increment. Thus the carry will be propagate to the previous column. Looks like another loop:
// Loop: number of positions
int propagation_position = position - 1;
while (propagation_position >= 0)
{
while (number[position] < LAST_CHAR)
{
number[position] = number[position] + 1; // Increment to next digit, same position.
Print_Number(number);
}
// Propagate the carry.
while (propagation_position >= 0)
{
if (number[propagation_position] != LAST_CHAR)
{
++number[propagation_position];
number[propagation_position + 1] = FIRST_CHAR;
break;
}
--propagation_position;
}
position = 0;
}
The above new fragment has an outer while loop and a second inner while loop. The outer while loop controls the digit position. The second inner while loop handles the carry.
The whole program is designed so that you can adjust the number of digit positions and the number of digits in the sequence.
Summary
The brute force method for printing all the combinations is like counting numbers. The same principles apply: when the last digit is incremented, it is replaced by the first digit and the digit of the next column is incremented. This is repeated until all positions have been counted.
Walk through the above code with debugger or pen and paper to find any defects and understand the algorithm.
After you understand the algorithm, search your favorite C++ reference for "c++ combination permutation algorithm".
Is there any technique for finding the reverse when there are zeros at the end.
While following the algorithm of %10 technique the result is 52. And the 0's are missing.
I have got the reverse by just printing the reminders (with 0's). But I am not satisfied as I wish to display the answer as the value in a variable.
Kindly tell me is there any technique to store a value 005 to a variable and also to display 005 (please don't use String or Character or array).
Numbers are stored as binary 0 and 1 and so they always have leading 0's which are chopped off. e.g. a 64-bit integer has 64-bit bits, always and when it is printed these leading 0's are dropped.
You need to know how many leading zeros you want to keep and only use that many when you print. i.e. you can record how many leading zeros there were in a normal number without encoding it e.g. by adding a 1 at the start. i.e. 0052 is recorded as 10052 and you skip the first digit when you print.
If you need to store a single value you can do the following. I use do/while so that 0 becomes 10 and is printed as 0. The number 0 is the one place where not all leading zeros are dropped (as it would be empty otherwise)
This appears to be the solution you want and it should be basically the same in C or C++
static long reverse(long num) {
long rev = 1; // the 1 marks the start of the number.
do {
rev = rev * 10 + num % 10;
num /= 10;
} while(num != 0);
return rev;
}
// make the reversed number printable.
static String toStringReversed(long num) {
return Long.toString(num).substring(1);
}
long l = reverse(2500); // l = 10052
An alternative is to print the digits as you go and thus not need to store it.
e.g.
static void printReverse(long l) {
do {
System.out.print(l % 10);
l /= 10;
} while(l != 0);
}
or you can have the input record the number of digits.
static void printReverse(long l, int digits) {
for(int i = 0; i < digits; i++) {
System.out.print(l % 10);
l /= 10;
}
}
// prints leading zero backwards as well
printReverse(2500, 6); // original number is 002500
prints
005200
You cannot represent an integer with leading zeros as a single integer variable, that information is simply not part of the way bits are allocated in an integer. You must use something larger, i.e. a string or an array of individual (small integer) digits.
You can't store them in a simple integer variable because in binary format
00101 is same as 000101 which is same as 101 which only results into 5. The convertion between a decimal number and binary numbers don't consider leading zeroes so it is not possible to store leading zeroes with the same integer variable.
You can print it but you can't store the leading zeroes unless you use array of ints...
int num = 500;
while(num > 0)
{
System.out.print(num%10);
num = num/10;
}
Alternatively you can store the count of leading zeroes as a separate entity and combine them when ever you need to use. As shown below.
int num = 12030;
boolean leading=true;
int leadingCounter = 0;
int rev = 0;
while(num > 0)
{
int r = num%10;
if(r == 0 && leading == true)
leadingCounter++;
else
leading = false;
rev = rev*10 + r;
num = num/10;
}
for(int i = 1; i <= leadingCounter ; i++)
System.out.print("0");
System.out.println(rev);
I think the accepted answer is a good one, in that it both refutes the parts of the question that are wrong and also offers a solution that will work. However, the code there is all Java, and it doesn't expose the prettiest API. Here's a C++ version that based on the code from the accepted answer.
(Ha ha for all my talk, my answer didn't reverse the string! Best day ever!)
After going back to school and getting a degree, I came up with this answer: it has the makes the somewhat dubious claim of "not using strings" or converting any values to string. Can't avoid characters, of course, since we are printing the value in the end.
#include <ostream>
#include <iostream>
class ReverseLong {
public:
ReverseLong(long value) {
long num = value;
bool leading = true;
this->value = 0;
this->leading_zeros = 0;
while (num != 0) {
int digit = num % 10;
num = num / 10;
if (leading && digit == 0) {
this->leading_zeros += 1;
} else {
this->value = this->value * 10 + digit;
leading = false;
}
}
};
friend std::ostream & operator<<(std::ostream& out, ReverseLong const & r);
private:
long value;
int leading_zeros;
};
std::ostream & operator<<(std::ostream& out, ReverseLong const & r) {
for (int i =0; i < r.leading_zeros; i++) {
out << 0;
}
out << r.value;
return out;
};
int main () {
ReverseLong f = ReverseLong(2500); // also works with numbers like "0"!
std::cout << f << std::endl; / prints 0052
};