I am self-studying C++ and the book "Programming-Principles and Practices Using C++" by Bjarne Stroustrup. One of the "Try This" asks this:
Implement square() without using the multiplication operator; that is, do the x*x by repeated addition (start a
variable result at 0 and add x to it x times). Then run some version of “the first program” using that square().
Basically, I need to make a square(int x) function that will return the square of it without using the multiplication operator. I so far have this:
int square(int x)
{
int i = 0;
for(int counter = 0; counter < x; ++counter)
{
i = i + x;
}
return i;
}
But I was wondering if there was a better way to do this. The above function works, but I am highly sure it is not the best way to do it. Any help?
Mats Petersson stole the idea out of my head even before I thought to think it.
#include <iostream>
template <typename T>
T square(T x) {
if(x < 0) x = T(0)-x;
T sum{0}, s{x};
while(s) {
if(s & 1) sum += x;
x <<= 1;
s >>= 1;
}
return sum;
}
int main() {
auto sq = square(80);
std::cout << sq << "\n";
}
int square(int x) {
int result = { 0 };
int *ptr = &result;
for (int i = 0; i < x; i++) {
*ptr = *ptr + x;
}
return *ptr;
}
I am reading that book atm. Here is my solution.
int square(int x)
{
int result = 0;
for (int counter = 0; counter < x; ++counter) result += x;
return result;
}
int square(int n)
{
// handle negative input
if (n<0) n = -n;
// Initialize result
int res = n;
// Add n to res n-1 times
for (int i=1; i<n; i++)
res += n;
return res;
}
//Josef.L
//Without using multiplication operators.
int square (int a){
int b = 0; int c =0;
//I don't need to input value for a, because as a function it already did it for me.
/*while(b != a){
b ++;
c = c + a;}*/
for(int b = 0; b != a; b++){ //reduce the workload.
c = c +a;
//Interesting, for every time b is not equal to a, it will add one to its value:
//In the same time, when it add one new c = old c + input value will repeat again.
//Hence when be is equal to a, c which intially is 0 already add to a for a time.
//Therefore, it is same thing as saying a * a.
}
return c;
}
int main(void){
int a;
cin >>a;
cout <<"Square of: "<<a<< " is "<<square(a)<<endl;
return 0;
}
//intricate.
In term of the running time complexity,your implementation is clear and simply enough,its running time is T(n)=Θ(n) for input n elements.Of course you also can use Divide-and-Conquer method,assuming split n elements to n/2:n/2,and finally recursive compute it then sum up two parts,that running time will be like
T(n)=2T(n/2)+Θ(n)=Θ(nlgn),we can find its running time complexity become worse than your implementation.
You can include <math.h> or <cmath> and use its sqrt() function:
#include <iostream>
#include <math.h>
int square(int);
int main()
{
int no;
std::cin >> no;
std::cout << square(no);
return 0;
}
int square(int no)
{
return pow(no, 2);
}
Related
I tried to write quicksort by myself and faced with problem that my algorithm doesn't work.
This is my code:
#include <iostream>
#include <vector>
using namespace std;
void swap(int a, int b)
{
int tmp = a;
a = b;
b = tmp;
}
void qsort(vector <int> a, int first, int last)
{
int f = first, l = last;
int mid = a[(f + l) / 2];
do {
while (a[f] < mid) {
f++;
}
while (a[l] > mid) {
l--;
}
if (f <= l) {
swap(a[f], a[l]);
f++;
l--;
}
} while (f < l);
if (first < l) {
qsort(a, first, l);
}
if (f < last) {
qsort(a, f, last);
}
}
int main()
{
int n;
cin >> n;
vector <int> a;
a.resize(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
qsort(a, 0, n - 1);
for (int i = 0; i < n; i++) {
cout << a[i] << ' ';
}
return 0;
}
My sort is similar to other that described on the Internet and I can't find where I made a mistake.
Even when I change sort function, the problem was not solved.
You don't pass qsort the array you want to sort, you pass it the value of that array. It modifies the value that was passed to it, but that has no effect on the array.
Imagine if you had this code:
void foo(int a)
{
a = a + 1;
}
Do you think if I call this like this foo(4); that foo is somehow going to turn that 4 into a 5? No. It's going to take the value 4 and turn it into the value 5 and then throw it away, since I didn't do anything with the modified value. Similarly:
int f = 4;
foo(f);
This will pass the value 4 to foo, which will increment it and then throw the incremented value away. The value f has after this will still be 4 since nothing ever changed f.
You meant this:
void qsort(vector <int>& a, int first, int last)
Your swap has the same problem. It swaps the values of a and b, but then never does anything with the value of a or b. So it has no effect. How could it? Would swap(3, 4); somehow change that 3 into a 4 and vice-versa? What would that even mean?
Your swap does not swap anything. You should write tests not only for the whole program but for as small pieces as possible. At least you should test single functions. Try this:
int main() {
int a= 42;
int b= 0;
std::cout << "before " << a << " " << b << "\n";
swap(a,b);
std::cout << "after " << a << " " << b << "\n";
}
This is "poor mans testing". For automated tests you should use a testing framework.
Then read about pass by reference. (While doing so you hopefully also realize the issue with not passing the vector to qsort by reference.)
Then use std::swap instead of reinventing a wheel.
I Found two error on your code
void swap(int a, int b) This method is not working, cause is receive value only and swap , but the original one is not updated.
void swap(int *a, int *b)
{
int t;
t = *b;
*b = *a;
*a = t;
}
swap(&a, &b);
And you pass vactor which also pass value. replace your void qsort(vector <int> &a, int first, int last) method.
I am new to C++. I am trying to define a binary converter function and return a pointer. Then U want to display generated binary in the main function:
#include <iostream>
using namespace std;
int* binary_con(int n)
{
int i;
int binary[100];
for (i = 0; n > 0; i++)
{
binary[i] = n % 2;
n = n / 2;
}
return binary;
}
int main()
{
int n;
int* a;
cout << "Input the number:";
cin >> n;
a = binary_con(n);
while (*a)
{
cout << *a;
a++;
}
return 0;
}
But after I run my code, I got this:
Can anyone explain this to me?
you can't return an array from a function, the way is to pass that array as an argument to the functionm using this approach:
void binary_con(int n, int *binary)
now you have access to binary array inside your function, hence you can edit it and see the changes outside of the function without returning anything.
inside your main, instead of writing a = binary_con(n);, you should write this:
binary_con(n, a);
I solved this problem from codeforces: https://codeforces.com/problemset/problem/1471/B. But when I upload it it says memory limit exceeded. How can I reduce the memory usage? I used C++ for the problem. The problem was the following: "You have given an array a of length n and an integer x to a brand new robot. What the robot does is the following: it iterates over the elements of the array, let the current element be q. If q is divisible by x, the robot adds x copies of the integer qx to the end of the array, and moves on to the next element. Note that the newly added elements could be processed by the robot later. Otherwise, if q is not divisible by x, the robot shuts down.
Please determine the sum of all values of the array at the end of the process".
This is the code:
#include <iostream>
#include <cstdlib>
#include <vector>
using namespace std;
int main()
{
vector<int> vec;
vector<int> ans;
int temp;
int t;
cin >> t;
int a = 0;
int n, x;
for(int i=0; i<t; i++){
cin >> n >> x;
while(a<n){
cin >> temp;
a++;
vec.push_back(temp);
}
int q = 0;
while(true){
if(vec[q]%x == 0){
for(int copies=0; copies<x; copies++){
vec.push_back(vec[q]/x);
}
}
else{
break;
}
q++;
}
int sum = 0;
for(int z: vec){
sum += z;
}
ans.push_back(sum);
vec.clear();
a = 0;
}
for(int y: ans){
cout << y << endl;
}
return 0;
}
Thanks.
You don't need to build the array as specified to compute the sum
You might do:
int pow(int x, int n)
{
int res = 1;
for (int i = 0; i != n; ++i) {
res *= x;
}
return res;
}
int compute(const std::vector<int>& vec, int x)
{
int res = 0;
int i = 0;
while (true) {
const auto r = pow(x, i);
for (auto e : vec) {
if (e % r != 0) {
return res;
}
res += e;
}
++i;
}
}
Demo
Consider:
If you find an indivisible number in the original array, you're going to stop before you reach the numbers you have added (so they don't affect the result).
If you add q/x to the array but q/x isn't divisible by x, you're going to stop there when you reach it, if you haven't already stopped earlier. (On the other hand, if q/x is divisible by x, the sum of x copies of q/x is q, so adding them is equivalent to adding q.)
So you don't need to expand the array, you just need to sum the elements and - on the side - keep the sum of all the numbers you would have expanded with until you find one that is not a multiple of x.
Then you either add that to the sum of the array or not, depending on whether you reached the end of the array.
I'm trying to implement the Sieve by myself and with no help other than the algorithm provided...
#include <iostream>
using namespace std;
void findPrimeNumbers(int number) {
int n=0;
bool* boolArray = new bool[number]();
for(int i=0; i<number; i++) {
boolArray[i] = true;
}
for(int i = 2; i<(int)sqrt(number); i++) {
cout << "calculating...\n";
if(boolArray[i]) {
for(int j=(i^2+(n*i)); j<number; n++)
boolArray[j] = false;
}
if(boolArray[i])
cout << i << "\n";
}
return;
}
int main()
{
findPrimeNumbers(55);
system("pause");
return 0;
}
Except the program is hanging on line 37; specifically, "boolArray[j] = false". It's never exiting that loop, and I don't know why.
Edited: Ok, this fixes the hang but still isn't right, but don't answer, I want to figure it out :)
#include <iostream>
#include <cmath>
using namespace std;
void findPrimeNumbers(int number) {
int n=0;
bool* boolArray = new bool[number]();
for(int i=0; i<number; i++) {
boolArray[i] = true;
}
for(int i = 2; i<sqrt(number); i++) {
if(boolArray[i]) {
for (int j = pow(i,2) + n*i; j <= number; j = pow(i, 2) + (++n*i))
boolArray[j] = false;
}
if(boolArray[i] && number % i == 0)
cout << i << "\n";
}
return;
}
int main()
{
findPrimeNumbers(13195);
system("pause");
return 0;
}
Beyond the error pointed out by #Rapptz (^ is bitwise xor), you are incrementing n instead of j, so the termination condition is never reached.
Two problems:
The ^ operator is not the exponent operator like it is in some other languages. Just multiply i by itself instead (i*i).
your for loop:
for(int j=(i^2+(n*i)); j<number; n++)
boolArray[j] = false;
does not reevaluate the initial condition each loop. You need to reevaluate the condition at the beginning of the for loop:
for(int n=0; j<number; n++)
{
j=(i*i+(n*i));
boolArray[j] = false;
}
Your issue is the line i^2+(n*i) like the comments point out, operator^ is the XOR operator, not exponentiation. In order to exponentiate something you have to include the <cmath> header and call std::pow(a,b) where it is equivalent to the mathematical expression a^b.
Although you didn't ask for code review, it should be noted that using dynamic allocation for a bool array is probably not a good idea. You should use std::vector<bool> and a proper reserve call. It should also be noted that the pow call would be completely unnecessary, as you are only multiplying it by itself (i.e. 2^2 is the same as 2*2).
A better naive prime sieve would be something similar to this:
#include <vector>
#include <iostream>
template<typename T>
std::vector<T> generatePrimes(unsigned int limit) {
std::vector<T> primes;
std::vector<bool> sieve((limit+1)/2);
if(limit > 1) {
primes.push_back(2);
for(unsigned int i = 1, prime = 3; i < sieve.size(); ++i, prime += 2) {
if(!sieve[i]) {
primes.push_back(prime);
for(unsigned int j = (prime*prime)/2; j < sieve.size(); j += prime)
sieve[j] = true;
}
}
}
return primes;
}
int main() {
std::vector<unsigned> primes = generatePrimes<unsigned>(1000000);
for(auto& i : primes)
std::cout << i << '\n';
}
You can see it here.
You have a number of problems:
int j=(i^2+(n*i))
^ is not power in C++, it's the bitwise XOR operator. To fix this, you'll need to #include <cmath> and utilize pow, or simply use i * i.
Secondly, as others have mentioned, you are incrementing n. The easiest fix for this is to use a while loop instead:
int j = std::pow(i, 2) + (n*i);
while(j < number) {
//Set bool at index to false
j += i;
}
Thirdly, you have a memory leak - you new without a delete. Further, there's no reason to use new here, instead you should have:
bool b[number];
This will deallocate b automatically when the function exits.
Finally, why return at the bottom of a void function? Technically you can do it, but there is no reason to.
I have been working on this for 24 hours now, trying to optimize it. The question is how to find the number of trailing zeroes in factorial of a number in range of 10000000 and 10 million test cases in about 8 secs.
The code is as follows:
#include<iostream>
using namespace std;
int count5(int a){
int b=0;
for(int i=a;i>0;i=i/5){
if(i%15625==0){
b=b+6;
i=i/15625;
}
if(i%3125==0){
b=b+5;
i=i/3125;
}
if(i%625==0){
b=b+4;
i=i/625;
}
if(i%125==0){
b=b+3;
i=i/125;
}
if(i%25==0){
b=b+2;
i=i/25;
}
if(i%5==0){
b++;
}
else
break;
}
return b;
}
int main(){
int l;
int n=0;
cin>>l; //no of test cases taken as input
int *T = new int[l];
for(int i=0;i<l;i++)
cin>>T[i]; //nos taken as input for the same no of test cases
for(int i=0;i<l;i++){
n=0;
for(int j=5;j<=T[i];j=j+5){
n+=count5(j); //no of trailing zeroes calculted
}
cout<<n<<endl; //no for each trialing zero printed
}
delete []T;
}
Please help me by suggesting a new approach, or suggesting some modifications to this one.
Use the following theorem:
If p is a prime, then the highest
power of p which divides n! (n
factorial) is [n/p] + [n/p^2] +
[n/p^3] + ... + [n/p^k], where k is
the largest power of p <= n, and [x] is the integral part of x.
Reference: PlanetMath
The optimal solution runs in O(log N) time, where N is the number you want to find the zeroes for. Use this formula:
Zeroes(N!) = N / 5 + N / 25 + N / 125 + ... + N / 5^k, until a division becomes 0. You can read more on wikipedia.
So for example, in C this would be:
int Zeroes(int N)
{
int ret = 0;
while ( N )
{
ret += N / 5;
N /= 5;
}
return ret;
}
This will run in 8 secs on a sufficiently fast computer. You can probably speed it up by using lookup tables, although I'm not sure how much memory you have available.
Here's another suggestion: don't store the numbers, you don't need them! Calculate the number of zeroes for each number when you read it.
If this is for an online judge, in my experience online judges exaggerate time limits on problems, so you will have to resort to ugly hacks even if you have the right algorithm. One such ugly hack is to not use functions such as cin and scanf, but instead use fread to read a bunch of data at once in a char array, then parse that data (DON'T use sscanf or stringstreams though) and get the numbers out of it. Ugly, but a lot faster usually.
This question is from codechef.
http://www.codechef.com/problems/FCTRL
How about this solution:
#include <stdio.h>
int a[] = {5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625};
int main()
{
int i, j, l, n, ret = 0, z;
scanf("%d", &z);
for(i = 0; i < z; i++)
{
ret = 0;
scanf("%d", &n);
for(j = 0; j < 12; j++)
{
l = n / a[j];
if(l <= 0)
break;
ret += l;
}
printf("%d\n", ret);
}
return 0;
}
Any optimizations???
Knows this is over 2 years old but here's my code for future reference:
#include <cmath>
#include <cstdio>
inline int read()
{
char temp;
int x=0;
temp=getchar_unlocked();
while(temp<48)temp=getchar_unlocked();
x+=(temp-'0');
temp=getchar_unlocked();
while(temp>=48)
{
x=x*10;
x+=(temp-'0');
temp=getchar_unlocked();
}
return x;
}
int main()
{
int T,x,z;
int pows[]={5,25,125,625,3125,15625,78125,390625,1953125,9765625,48828125,244140625};
T=read();
for(int i=0;i<T;i++)
{
x=read();
z=0;
for(int j=0;j<12 && pows[j]<=x;j++)
z+=x/pows[j];
printf("%d\n",z);
}
return 0;
}
It ran in 0.13s
Here is my accepted solution. Its score is 1.51s, 2.6M. Not the best, but maybe it can help you.
#include <iostream>
using namespace std;
void calculateTrailingZerosOfFactoriel(int testNumber)
{
int numberOfZeros = 0;
while (true)
{
testNumber = testNumber / 5;
if (testNumber > 0)
numberOfZeros += testNumber;
else
break;
}
cout << numberOfZeros << endl;
}
int main()
{
//cout << "Enter number of tests: " << endl;
int t;
cin >> t;
for (int i = 0; i < t; i++)
{
int testNumber;
cin >> testNumber;
calculateTrailingZerosOfFactoriel(testNumber);
}
return 0;
}
#include <cstdio>
int main(void) {
long long int t, n, s, i, j;
scanf("%lld", &t);
while (t--) {
i=1; s=0; j=5;
scanf("%lld", &n);
while (i != 0) {
i = n / j;
s = s + i * (2*j + (i-1) * j) / 2;
j = j * 5;
}
printf("%lld\n", s);
}
return 0;
}
You clearly already know the correct algorithm. The bottleneck in your code is the use of cin/cout. When dealing with very large input, cin is extremely slow compared to scanf.
scanf is also slower than direct methods of reading input such as fread, but using scanf is sufficient for almost all problems on online judges.
This is detailed in the Codechef FAQ, which is probably worth reading first ;)