I would like to separate 789 into its digits and insert them into myvector
in such a way that 7 goes into the first element, 8 into the second element etc.
Yes.
1 Store int number into a string
2 Parse the string into characters (which will be ur digits)
3 Convert each character (ie: digit) into an integer again with stringstream (for example)
4 Store the final digit(s) into myvector
int value = 234;
int digits = log10((float)value) + 1; //this determines the number of digits
for (int i = digits - 1; i > 0; i--) {
int divisor = pow((float)10, i);
int digit = value / divisor;
value -= digit * divisor;
//insert digit into vector
}
//insert last digit into vector
Careless use of floating point, while arguably being cool, is also prone to inaccuracies.
1 2 3
int value = 99999999 ;
int digits = std::log10((float)value) + 1; //this determines the number of digits
std::cout << digits << '\n' ; // prints '9' on my implementation
EDIT:
> Please how do you put the code in the purple field ?
Select the code and click on the "<>" button on the right.
U'r right JLBorges. U do have the best solution. I just liked the nonstandard approach of logs cuz I wouldn't have thought of it.
If u'r still here coolbran u should implement JLBorges's vector approach. Sorry if I mislead u with my previous comment...
ps: unless of course ssrun can plug those potential 'inaccuracies' hehe XD
Although I suggested something similar to SSRUN's function in another thread, I would have to suggest JLBorge's.
1. It doesn't use log(), which is a decent improvement. (But instead has 2 divisions per cycle, although since integer division is much better on processors these days this isn't too bad)
2. It doesn't rely on FP math for precise results.
3. It has less assignment operations. (But instead uses reverse())
# include <iostream>
# include <vector>
# include <sstream>
usingnamespace std;
int get_nbr_digits(int);
int main()
{
stringstream ss;
string str;
int number = 789;
int dgtNbr = get_nbr_digits(number);
ss << number;
ss >> str;
vector<int>myVector(dgtNbr);
for(int i=0;i<dgtNbr;i++)myVector[i] = str[i]-'0';
for(int i=0;i<dgtNbr;i++)
cout << myVector[i] << endl;
}
int get_nbr_digits(int nbr)
{
// This function calculates the number of the digits in a number giving
// which is in this case the parameter nbr
// PS : If you know the number of the digits you can abandon this function ,
// if you get an input this is the right function for the job
int increase = 0;
for(int i=0,j=1;i<10;i++,j*=10)// I choose 10 because INT_MAX contain 10 digits
{
if((nbr/j)!=0)increase++;
elsebreak;
}return increase;
}
soranz: > I just liked the nonstandard approach of logs cuz I wouldn't have thought of it.
It is an elegant and mathematically correct algorithm. Lots to like about it.
I just wanted to point out that the intrinsic nature of floating point arithmetic and the numerical approximations in functions like std::log10() gives rise to non-trivial problems in its implementation.
ssrun: > Sorry, didn't realize log10 doesn't calculate properly at high values.
There is absolutely nothing to be apologetic about - it is an elegant algorithm. If the thread made you realize (or reminded you once again) that there are accuracy issues involved, you should be glad.
PS: Hadn't looked at the replies earlier (till a PM made me look at this thread again); hence this late responses.
#include <iostream>
#include <vector>
void split_into_digits( std::vector<unsignedint> &v, unsignedint value )
{
constexprunsignedint base = 10;
unsignedint digit = value % base;
if ( value /= base ) split_into_digits( v, value );
v.push_back( digit );
}
int main()
{
std::vector<unsignedint> v;
split_into_digits( v, 12345678 );
for ( auto x : v ) std::cout << x << ' ';
std::cout << std::endl;
return 0;
}
@JLBorges
Yeah, but it doesn't buy much - it is not tail recursion.
I tried to implement a tail recursion with MS VC++ 2010 but I did not find which compiler options must be set that the compiler will generate the code for the tail recursion. So I do not rely upon the tail recursion.