This question already has answers here:
Base-2 (Binary) Representation Using Python
(2 answers)
Closed 9 years ago.
I am writing a quick program to decompose a number into powers of 2. Is this an efficient way to do it:
pows=[]
pos = 0
while n>0:
if n%2==1: pows.append(2**pos)
n/=2
pos+=1
I've written this in Python but I'm also interested in how it's done in C++.
I don't know if this is a "smart" way to do it or if it's considered horribly inefficient.
The most natural implementation in C++ would use a bit mask for
the powers of two, something like:
std::vector<unsigned> p2;
unsigned m = 1;
while ( m != 0 ) {
if ( (m & i) != 0 ) {
p2.push_back( m );
}
m <<= 1;
}
You certainly don't want to call the pow function each time in
the loop. A somewhat trickery way, which is likely faster
(since it will usually pass less times in the loop) would be:
std::vector<unsigned> p2;
std::cout << i << ": ";
while ( i != 0 ) {
unsigned n = i & i - 1;
p2.push_back( i ^ n );
i = n;
}
I would recommend the first (which is readily understandable)
unless the profiler really says you must use the second.
Any modern compiler is probably going to be smart enough to optimize this. Get your code to run correctly first, and worry about optimizing for speed after profiling (if it is too slow).
Related
input : integer ( i'll call it N ) and (1 <= N <= 5,000,000 )
output : integer, multiple of N and only contains 0,7
Ex.
Q1 input : 1 -> output : 7 ( 7 mod 1 == 0 )
Q2 input : 2 -> output : 70 ( 70 mod 2 == 0 )
#include <string>
#include <iostream>
using namespace std;
typedef long long ll;
int remaind(string num, ll m)
{
ll mod = 0;
for (int i = 0; i < num.size(); i++) {
int digit = num[i] - '0';
mod = mod * 10 + digit;
mod = mod % m;
}
return mod;
}
int main()
{
int n;
string ans;
cin >> n;
ans.append(n, '7');
for (int i = ans.length() - 1; i >= 0; i--)
{
if (remaind(ans, n) == 0)
{
cout << ans;
return 0;
}
ans.at(i) = '0';
}
return 0;
}
is there a way to lessen the time complexity?
i just tried very hard and it takes little bit more time to run while n is more than 1000000
ps. changed code
ps2. changed code again because of wrong code
ps3. optimize code again
ps4. rewrite post
Your approach is wrong, let's say you divide "70" by 5. Then you result will be 2 which is not right (just analyze your code to see why that happens).
You can really base your search upon numbers like 77777770000000, but think more about that - which numbers you need to add zeros and which numbers you do not.
Next, do not use strings! Think of reminder for a * b if you know reminder of a and reminder of b. When you program it, be careful with integer size, use 64 bit integers.
Now, what about a + b?
Finally, find reminders for numbers 10, 100, 1000, 10000, etc (once again, do not use strings and still try to find reminder for any power of 10).
Well, if you do all that, you'll be able to easily solve the whole problem.
May I recommend any of the boost::bignum integer classes?
I suspect uint1024_t (or whatever... they also have 128, 256, and 512, bit ints already typedefed, and you can declare your own easily enough) will meet your needs, allowing you to perform a single %, rather than one per iteration. This may outweigh the performance lost when using bignum vs c++'s built-in ints.
2^1024 ~= 1.8e+308. Enough to represent any 308 digit number. That's probably excessive.
2^512 ~= 1.34e+154. Good for any 154 digit number.
etc.
I suspect you should first write a loop that went through n = 4e+6 -> 5e+6 and wrote out which string got the longest, then size your uint*_t appropriately. If that longest string length is more than 308 characters, you could just whip up your own:
typedef number<cpp_int_backend<LENGTH, LENGTH, unsigned_magnitude, unchecked, void> > myReallyUnsignedBigInt;
The modulo operator is probably the most expensive operation in that inner loop. Performing once per iteration on the outer loop rather than at the inner loop (O(n) vs O(n^2)) should save you quite a bit of time.
Will that plus the whole "not going to and from strings" thing pay for bignum's overhead? You'll have to try it and see.
In C++, I should write a program where the app detects which numbers are divisible by 3 from 1 till 10 and then multiply all of them and print the result. That means that I should multiply 3,6,9 and print only the result, which is 162, but I should do it by using a "While" loop, not just multiplying the 3 numbers with each other. How should I write the code of this? I attached my attempt to code the problem below. Thanks
#include <iostream>
using namespace std;
int main() {
int x, r;
int l;
x = 1;
r = 0;
while (x < 10 && x%3==0) {
r = (3 * x) + 3;
cout << r;
}
cin >> l;
}
Firstly your checking the condition x%3 == 0 brings you out of your while - loop right in the first iteration where x is 1. You need to check the condition inside the loop.
Since you wish to store your answer in variable r you must initialize it to 1 since the product of anything with 0 would give you 0.
Another important thing is you need to increment the value of x at each iteration i.e. to check if each number in the range of 1 to 10 is divisible by 3 or not .
int main()
{
int x, r;
int l;
x = 1;
r = 1;
while (x < 10)
{
if(x%3 == 0)
r = r*x ;
x = x + 1; //incrementing the value of x
}
cout<<r;
}
Lastly I have no idea why you have written the last cin>>l statement . Omit it if not required.
Ok so here are a few hints that hopefully help you solving this:
Your approach with two variables (x and r) outside the loop is a good starting point for this.
Like I wrote in the comments you should use *= instead of your formula (I still don't understand how it is related to the problem)
Don't check if x is dividable by 3 inside the while-check because it would lead to an too early breaking of the loop
You can delete your l variable because it has no affect at the moment ;)
Your output should also happen outside the loop, else it is done everytime the loop runs (in your case this would be 10 times)
I hope I can help ;)
EDIT: Forget about No.4. I didn't saw your comment about the non-closing console.
int main()
{
int result = 1; // "result" is better than "r"
for (int x=1; x < 10; ++x)
{
if (x%3 == 0)
result = result * x;
}
cout << result;
}
or the loop in short with some additional knowledge:
for (int x=3; x < 10; x += 3) // i know that 3 is dividable
result *= x;
or, as it is c++, and for learning purposes, you could do:
vector<int> values; // a container holding integers that will get the multiples of 3
for (int x=1; x < 10; ++x) // as usual
if ( ! x%3 ) // same as x%3 == 0
values.push_back(x); // put the newly found number in the container
// now use a function that multiplies all numbers of the container (1 is start value)
result = std::accumulate(values.begin(), values.end(), 1, multiplies<int>());
// so much fun, also get the sum (0 is the start value, no function needed as add is standard)
int sum = std::accumulate(values.begin(), values.end(), 0);
It's important to remember the difference between = and ==. = sets something to a value while == compares something to a value. You're on the right track with incrementing x and using x as a condition to check your range of numbers. When writing code I usually try and write a "pseudocode" in English to organize my steps and get my logic down. It's also wise to consider using variables that tell you what they are as opposed to just random letters. Imagine if you were coding a game and you just had letters as variables; it would be impossible to remember what is what. When you are first learning to code this really helps a lot. So with that in mind:
/*
- While x is less than 10
- check value to see if it's mod 3
- if it's mod 3 add it to a sum
- if not's mod 3 bump a counter
- After my condition is met
- print to screen pause screen
*/
Now if we flesh out that pseudocode a little more we'll get a skeletal structure.
int main()
{
int x=1//value we'll use as a counter
int sum=0//value we'll use as a sum to print out at the end
while(x<10)//condition we'll check against
{
if (x mod 3 is zero)
{
sum=x*1;
increment x
}
else
{
increment x
}
}
//screen output the sum the sum
//system pause or cin.get() use whatever your teacher gave you.
I've given you a lot to work with here you should be able to figure out what you need from this. Computer Science and programming is hard and will require a lot of work. It's important to develop good coding habits and form now as it will help you in the future. Coding is a skill like welding; the more you do it the better you'll get. I often refer to it as the "Blue Collar Science" because it's really a skillset and not just raw knowledge. It's not like studying history or Biology (minus Biology labs) because those require you to learn things and loosely apply them whereas programming requires you to actually build something. It's like welding or plumbing in my opinion.
Additionally when you come to sites like these try and read up how things should be posted and try and seek the "logic" behind the answer and come up with it on your own as opposed to asking for the answer. People will be more inclined to help you if they think you're working for something instead of asking for a handout (not saying you are, just some advice). Additionally take the attitude these guys give you with a grain of salt, Computer Scientists aren't known to be the worlds most personable people. =) Good luck.
This question already has answers here:
C++ - how to find the length of an integer
(17 answers)
Closed 7 years ago.
In Java, I use
int length = String.valueOf(input).length();
to find the length of an integer.
My question is: Are there any similar ways to do so in C++?
I have already tried the for loops and while loops such as:
while (input > 0){
input/=10;
count++;
So, apart from the loops are there anything else available in C++. Thank you for your answer.
If you want an exact counterpart of what you have written in Java, you can use:
int length = to_string(input).length();
Note that to_string is a C++11 feature. Also, be careful with negative numbers.
The number of digits can be calculated without converting to a string first by using the number's logarithm:
std::size_t intlen(int i) {
if (i == 0) return 1;
else if (i < 0) return 2 + static_cast<std::size_t>(std::log10(-i));
else if (i > 0) return 1 + static_cast<std::size_t>(std::log10(i));
}
The logartihm is only defined for positive numbers, so negatives and zero have to be handled separately, counting the - sign as an additional character. Replace log10 by log2 to obtain the number of binary digits (this is possible for any base).
Note however that converting to strings first (e.g. by using std::to_string) is a locale-dependent operation and can thus yield different results for different language settings - some locales insert a thousands separator (e.g. 100,000) which will not show up using the above formula.
unsigned int number_of_digits = 0;
do {
++number_of_digits;
n /= base; } while (n);
// n is your base number.
Talking about pre-C++11, you can use the same approach, but with sprintf.
Convert integer to a char array, and then get its length:
char buffer[30];
int length = sprintf(buffer, "%d", input);
Here is the working IDEOne example.
Apart from the loops there is recursion. For example, for positive integers you can do:
unsigned int len(unsigned int n)
{
return n ? len(n/10)+1 : 0;
}
This question already has answers here:
Making a square() function without x*x in C++
(7 answers)
Closed 4 years ago.
I'm a beginner in programming and trying to learn C++ by the book Programming principles and practice using C++. In some parts of the book there are little exercises that you can try to do, one of this exercises is about calculating the square of a number, here is what my book says :
Implement square() without using the multiply operator, that is, do the x * x by repetead addition (start a variable result to 0 and add x to it x times).
I've already found a solution for this program but my first tentative was something like this :
#include <iostream>
int main()
{
int a = 0;
std::cout << "Enter an integer value : ";
std::cin >> a;
while (a < a * a)
{
a += a;
std::cout << a << "\n";
}
}
I know this code is wrong but I can't understand the output of the progam, if I enter 5 the program prints 10 20 30 40 50 until 8000, why the for loop doesn't stop when a is greater than its square ? I'm just curious to undersant why
Using multiplication when trying to avoid multiplication seems broken. What about this:
int r = 0;
for (int n = 0; n < a; ++n) {
r += a;
}
why the for loop doesn't stop when a is greater than its square ?
Because it never is. If you compare the graph of y=x^2 against the graph of y=x, you will see that the only time y=x is above, is when 0 < x < 1. That's never the case for integers1. Now, since we're talking about computers with limited storage here, there is a thing called overflow, which will cause a very large number to become a very small number. However, signed integer overflow is undefined behavior in C++. So once your loop gets to the point where overflow would happen, you cannot rely on the results.
1. Note that your loop is not set to stop just when a is greater than its square, but when it is greater than or equal to its square. So, your loop will actually stop if a is 0 or 1.
I am in the midst of solving a simple combination problem whose solution is 2^(n-1).
The only problem is 1 <= n <= 2^31 -1 (max value for signed 32 bit integer)
I tried using Java's BigInteger class but It times out for numbers 2^31/10^4 and greater, so that clearly doesn't work out.
Furthermore, I am limited to using only built-in classes for Java or C++.
Knowing I require speed, I chose to build a class in C++ which does arithmetic on strings.
Now, when I do multiplication, my program multiplies similarly to how we multiply on paper for efficiency (as opposed to repeatedly adding the strings).
But even with that in place, I can't multiply 2 by itself 2^31 - 1 times, it is just not efficient enough.
So I started reading texts on the problem and I came to the solution of...
2^n = 2^(n/2) * 2^(n/2) * 2^(n%2) (where / denotes integer division and % denotes modulus)
This means I can solve exponentiation in a logarithmic number of multiplications. But to me, I can't get around how to apply this method to my code? How do I choose a lower bound and what is the most efficient way to keep track of the various numbers that I need for my final multiplication?
If anyone has any knowledge on how to solve this problem, please elaborate (example code is appreciated).
UPDATE
Thanks to everyone for all your help! Clearly this problem is meant to be solved in a realistic way, but I did manage to outperform java.math.BigInteger with a power function that only performs ceil(log2(n)) iterations.
If anyone is interested in the code I've produced, here it is...
using namespace std;
bool m_greater_or_equal (string & a, string & b){ //is a greater than or equal to b?
if (a.length()!=b.length()){
return a.length()>b.length();
}
for (int i = 0;i<a.length();i++){
if (a[i]!=b[i]){
return a[i]>b[i];
}
}
return true;
}
string add (string& a, string& b){
if (!m_greater_or_equal(a,b)) return add(b,a);
string x = string(a.rbegin(),a.rend());
string y = string(b.rbegin(),b.rend());
string result = "";
for (int i = 0;i<x.length()-y.length()+1;i++){
y.push_back('0');
}
int carry = 0;
for (int i =0;i<x.length();i++){
char c = x[i]+y[i]+carry-'0'-'0';
carry = c/10;
c%=10;
result.push_back(c+'0');
}
if (carry==1) result.push_back('1');
return string(result.rbegin(),result.rend());
}
string multiply (string&a, string&b){
string row = b, tmp;
string result = "0";
for (int i = a.length()-1;i>=0;i--){
for (int j= 0;j<(a[i]-'0');j++){
tmp = add(result,row);
result = tmp;
}
row.push_back('0');
}
return result;
}
int counter = 0;
string m_pow (string&a, int exp){
counter++;
if(exp==1){
return a;
}
if (exp==0){
return "1";
}
string p = m_pow(a,exp/2);
string res;
if (exp%2==0){
res = "1"; //a^exp%2 is a^0 = 1
} else {
res = a; //a^exp%2 is a^1 = a
}
string x = multiply(p,p);
return multiply(x,res);
//return multiply(multiply(p,p),res); Doesn't work because multiply(p,p) is not const
}
int main(){
string x ="2";
cout<<m_pow(x,5000)<<endl<<endl;
cout<<counter<<endl;
return 0;
}
As mentioned by #Oli's answer, this is not a question of computing 2^n as that's trivially just a 1 followed by 0s in binary.
But since you want to print them out in decimal, this becomes a question of how to convert from binary to decimal for very large numbers.
My answer to that is that it's not realistic. (I hope this question just stems from curiosity.)
You mention trying to compute 2^(2^31 - 1) and printing that out in decimal. That number is 646,456,993 digits long.
Java BigInteger can't do it. It's meant for small numbers and uses O(n^2) algorithms.
As mentioned in the comments, there are no built-in BigNum libraries in C++.
Even Mathematica can't handle it: General::ovfl : Overflow occurred in computation.
Your best bet is to use the GMP library.
If you're just interested in seeing part of the answer:
2^(2^31 - 1) = 2^2147483647 =
880806525841981676603746574895920 ... 7925005662562914027527972323328
(total: 646,456,993 digits)
This was done using a close-sourced library and took roughly 37 seconds and 3.2 GB of memory on a Core i7 2600K # 4.4 GHz including the time needed to write all 646 million digits to a massive text file.
(It took notepad longer to open the file than needed to compute it.)
Now to answer your question of how to actually compute such a power in the general case, #dasblinkenlight has the answer to that which is a variant of Exponentiation by Squaring.
Converting from binary to decimal for large numbers is a much harder task. The standard algorithm here is Divide-and-Conquer conversion.
I do not recommend you try to implement the latter - as it's far beyond the scope of starting programmers. (and is also somewhat math-intensive)
You don't need to do any multiplication at all. 2^(n-1) is just 1 << (n-1), i.e. 1 followed by (n-1) zeros (in binary).
The easiest way to apply this method in your code is to apply it the most direct way - recursively. It works for any number a, not only for 2, so I wrote code that takes a as a parameter to make it more interesting:
MyBigInt pow(MyBigInt a, int p) {
if (!p) return MyBigInt.One;
MyBigInt halfPower = pow(a, p/2);
MyBigInt res = (p%2 == 0) ? MyBigInt.One : a;
return res * halfPower * halfPower;
}