Rotation of integers stored in an array - c++

I have made a simple program of rotation of integers in a given array.
#include <iostream>
using namespace std;
int main()
{
int t;
cin>>t;
long i,j,n,k,l,m,x;
long a[1000000];
for(i=0;i<t;i++){
cin>>n;
cin>>k;
for(j=0;j<n;j++){
cin>>a[j];
}
for(m=0;m<k;m++){
x=a[0];
for(j=1;j<n;j++){
x=a[j]+x;
a[j]=x-a[j];
x=x-a[j];
}
a[0]=x;
}
for(j=0;j<n;j++){
cout<<a[j]<<" ";
}
cout<<endl;
}
return 0;
}
The question can be found here. My code processes the small inputs easily, but when the input reaches to the order of thousands it takes well over a second and it fails due to that. Any suggestions on how to solve this problem?

Some notes that can be used to speed things up:
Rotating by K, when K>N, is equivalent to rotating by K%N (as each rotation of N is an expensive no-op).
You don't actually need to generate the rotated array; you just need to print the values as they would appear in the rotated array.
In fact, you don't (necessarily) need to store all of the input in an array, but just the part that can't be printed until the last value in the array is read. (This would get the input and output intermingled if both were through the console, but not if at least one were a file.)
These can be used to turn your O(N^2) solution into an O(N) one.

Related

time complexity of (A[i]^x)>(A[i]&x)

'Is it possible to further optimize the time complexity this piece of calculation "(y^x)>(y&x)" in c++?(you are allowed to change the Boolean operation into other forms, for example this can also be written as log2(y)!=log2(x) and this gives the same Boolean output but this has a higher time complexity with c++ compiler)'enter code here
#include <bits/stdc++.h>
using namespace std;
int main() {
// your code goes here
int t;cin>>t;
while(t--){
int n;cin>>n;int A[n];
for(int i=0;i<n;i++){cin>>A[i];}
int q;cin>>q;
while(q--){
int l,r,x;
cin>>l>>r>>x;int count=0;
for(int i=l-1;i<r;i++){
if((A[i]^x)>(A[i]&x)){count++;}
}
cout<<count<<endl;
}
}
return 0;
}
'This is the code im trying to optimize.... Please help in any way possible (number of inputs cant be changed)'
(y^x)>(y&x) is equivalent to nlz(y) != nlz(x) where nlz is a function that returns the number of leading zeroes of its input.
Therefore in order to count how often (A[i]^x)>(A[i]&x) is true for items in the array A, we could make a small array N where N[j] is the number of elements with nlz(A[i]) == j in array A. Then the number of times that (A[i]^x)>(A[i]&x) is true is equivalent to n - N[nlz(x)].
That way there is no loop over A where it really matters. Creating the array N still requires a loop over A, but only once for each iteration of the outer loop, not for each individual x.
C++20 has the nlz function built in under the name std::countl_zero.

Dynamic Programming Using STL Vectors Makes Program Freeze Beyond Certain Values

I wrote the following program, trying to optimize a recursive algorithm using Dynamic Programming.
#include <bits/stdc++.h>
using namespace std;
int mini(int n, vector<int> &memory){
if(n<memory.size()){
return memory[n];
}
else{
int m = (n+1)+mini(((n-1)/2), memory)+mini(((n-1)-((n-1)/2)), memory);
memory[n]=m;
return m;
}
}
int main(){
vector<int> memory={0, 2, 5};
int t;
cin >> t;
while(t--){
int n;
cin >> n;
cout << mini(n, memory) << "\n";
}
}
The base conditions for the recursive function are already specified inside the vector, and the function does work for the base conditions. It works correctly for mini(1), mini(2), ..., mini(5). Whenever I am trying anything from mini(6) or beyond, the program just freezes.
After a bit of debugging, the problem does seem to be that the function is unable to read any of the values that we are subsequently adding into the memory vector. Which is why the following works:
mini(5) = 6 + mini(2) + mini(2) //mini(2) is pre-specified in memory vector.
mini(4) = 5 + mini(1) + mini(2) //mini(1) and mini(2) are pre-specified.
However,
mini(6) = 7 + mini(2) + mini(3) //mini(3) is not pre-specified into vector memory.
Here, mini(3) should have been added into the vector and used, but the function somehow doesn't seem to be able to do that.
It seems that the function is unable to perform recursions beyond a single level. I have no idea why, and would very much prefer some reason why this is happening.
Following insights from the comments, the problem has been solved.
There were two issues with the initial program:
Trying to insert elements beyond the current size of the vector: To fix this issue, use an if statement before inserting elements to the vector to ensure that it has the correct capacity.
if(memory.capacity()<(n+1)){
memory.resize(n+1);
}
memory[n]=m;
Using items from memory that we did not previously insert: When we are resizing memory from the previous point, we are also creating empty values at spots that we did not insert into before. For example, mini(7) would insert the values of mini(3) and mini(7) into memory. The values of mini(4), mini(5) and mini(6) would remain 0. Later when we use the function, the values of mini(4), mini(5) and mini(6) would be found in the memory to be 0, and be used as such, leading to incorrect answers.
Fixing both errors, the revised function looks like this:
int mini(int n, vector<int> &memory){
if(n<memory.size() && memory[n]!=0){
return memory[n];
}
else{
int m = (n+1)+mini(((n-1)/2), memory)+mini(((n-1)-((n-1)/2)), memory);
if(memory.capacity()<(n+1)){
memory.resize(n+1);
}
memory[n]=m;
return m;
}
}

Why is my for loop running only 2 times instead of 10?

I am trying to find the third highest number in the array with O(n) space and time complexity.
MY program is obviously wrong but that is not the problem.
My for loop in the thirdhighestnum function seem to running only 2 times. I can't seem to find the reason for it. Can anyone help me. Sorry for such basic question I am a beginner here.
#include<iostream>
using namespace std;
int thirdhighestnum(int a[],int size)
{
cout<<" "<<size<<endl;
int first=a[0],second=0,third=0;
for(int i=1;i<size;i++)
{
cout<<a[i]<<";"<<endl;
if(a[i]>first)
{
first=a[i];
if(a[i+1]>first)
{
second=first;
first=a[i+1];
if(a[i+2]>first)
{ third=second;
second=first;
first=a[i+2];
}
}
cout<<i<<endl
return third;
}
}
}
int main()
{ int num,a[10];
cout<<"Enter the elements in the array"<<endl;
for(int i=0;i<10;i++)
cin>>a[i];
cout<<"Third highest number is "<<thirdhighestnum(a,10)<<endl;
return 0;
}
It's the location of your return third statement. The moment any number is larger than the first number, it exits the thirdhighestnum function and returns a value. Put it outside your for loop and it should be fine.
Actually it is executing only one time i.e. the first iteration only. When i=1 then it prints a[1] i.e. 2; after that it prints i i.e. 1 so it appears as 2;1 here you think it is printing 2 numbers.
The main problem is your return third statement which terminates your for loop in first iteration only.
This is known as nth_element and library function can do this for you.
As for why your code fails, there is a flaw in your logic
for(int i=1;i<size;i++)
{
// some code
if(a[i]>first)
{
// some more code
cout<<i<<endl
return third;
}
}
So your code exits the first time a[i] is greater than first.
[edit - After reading comments]
The generic name for this type of algorithm is a QuickSelect. It is unlikely you will find a faster algorithm, as this has been the subject of years of academic study.

cout doesn't works properly on my program, can somebody help me?

enter image description hereI am using the STL in c++ and inside a bucle the cout doesn't prints correctly a float.
my program ads values to a vector and then passes it to a function to see if the condition exist, actually it works perfectly but just the cout doesn't word, I already tried using printf() but it gave the same result.
note:please algo give me feedback on my question is the first time i do one and English is not my natal language
my code:
#include<bits/stdc++.h>
#include<vector>
using namespace std;
void isthereanumber(vector<float> array);
int main(){
string ans;vector<float> array;float number;
do{
fflush(stdin);
cout<<"insert a value for the vector: "<<endl;
cin>>number;
array.push_back(number);
fflush(stdin);
cout<<"would you like to keep adding values to the vector? "<<endl;
getline(cin,ans);
}while(ans.compare("yes")==0);
isthereanumber(array);
return 0;
}
void isthereanumber(vector<float> array){
float suma =0;
for(vector<float>::iterator i=array.begin();i!=array.end();i++){
for(vector<float>::iterator j=array.begin();j!=array.end();j++){
if(i!=j){
suma = suma+array[*j];
}
}
if(suma=array[*i]){
cout<<"there is a number that the addition of every number in the array except the number is equal to the number \n";fflush(stdin);
cout<<"the number is: "<<suma;/*here is the cout that doesnt works properly or perhabs is something else i don't know*/
return;
}
}
cout<<"there is not a number with such a condition: ";
return;
}
As stated by cleggus already there are some issues present. Those need to be adressed first. After that there's a logical error in that suma just keeps growing.
Given the input 5,5,10 once we test for 10 we would like suma to be set to 0 again for it to work but it will be something like 30 now instead.
That can be solved by moving suma inside the outer loop.
Working example for input 5,5,10: https://godbolt.org/z/gHT6jg
I think you may have a couple of issues...
In your for loops you are creating iterators to the vector, but rather than just dereferencing them to access the indexed element you are dereferencing them and then using that as an index to the same vector.
Also Your last if statement has an assignment = rather than a comparison ==.
I believe this is closer to what you are trying to achieve (sorry I haven't had time to compile and check):
for(vector<float>::iterator i=array.begin();i!=array.end();i++){
for(vector<float>::iterator j=array.begin();j!=array.end();j++){
if(i!=j){
suma = suma+*j;
}
}
if(suma==*i){
cout<<"there is a number that the addition of every number in the array except the number is equal to the number \n";fflush(stdin);
cout<<"the number is: "<<suma;/*here is the cout that doesnt works properly or perhabs is something else i don't know*/
return;
}
}

C++ program to compute lcm of numbers between 1 to 20 (project euler )

as the title explains this is a program to find lcm of numbers between 1 to 20. i found an algorithm to do this, here's the link
http://www.cut-the-knot.org/Curriculum/Arithmetic/LCM.shtml
there is a java applet on the webpage that might explain the algorithm better
Problem: i wrote the code compiler shows no error but when i run the code the program goes berserk, i guess may be some infinite loopig but i can't figure it out for the life of me. i use turbo c++ 4.5 so basically if anyone can look at the code and help me out it would be great . thanks in advance
Algorithm:
say we need to find lcm of 2,6,8
first we find the least of the series and add to it the number above it, i.e the series become
4,6,8
now we find the least value again and add to it the intitial value in the column i.e 2
6,6,8
so the next iteration becomes
8,6,8
8,12,8
10,12,8
10,12,16
12,12,16
14,12,16
14,18,16
16,18,16
18,18,16
18,18,24
20,18,24
20,24,24
22,24,24
24,24,24
as you can see at one point all numbers become equal which is our lcm
#include<iostream.h>
/*function to check if all the elements of an array are equal*/
int equl(int a[20], int n)
{
int i=0;
while(n==1&&i<20)
{
if (a[i]==a[i+1])
n=1;
else
n=0;
i++;
}
return n;
}
/*function to calculate lcm and return that value to main function*/
int lcm()
{
int i,k,j,check=1,a[20],b[20];
/*loading both arrays with numbers from 1 to 20*/
for(i=0;i<20;i++)
{
a[i]=i+1;
b[i]=i+1;
}
check= equl(a,1);
/*actual implementation of the algorith*/
while(check==0)
{
k=a[0]; /*looks for the least value in the array*/
for(i=0;i<20;i++)
{
if(a[i+1]<k)
{
k=a[i+1]; /*find the least value*/
j=i+1; /*mark the position in array */
}
else
continue;
}
a[j]=k+b[j]; /*adding the least value with its corresponding number*/
check= equl(a,1);
}
return (a[0]);
/*at this point all numbers in the array must be same thus any value gives us the lcm*/
}
void main()
{
int l;
l=lcm();
cout<<l;
}
In this line:
a[j]=k+b[j];
You use j but it is unitialized so it's some huge value and you are outside of the array bounds and thus you get a segmentation fault.
You also have some weird things going on in your code. void main() and you use cout without either saying std::cout or using namespace std; or something similar. An odd practice.
Also don't you think you should pass the arrays as arguments if you're going to make lcm() a function? That is int lcm(int a[], int b[]);.
You might look into using a debugger also and improving your coding practices. I found this error within 30 seconds of pasting your code into the compiler with the help of the debugger.
Your loop condition is:
while(n==1&&i<20)
So your equl function will never return 1 because if n happens to be 1 then the loop will just keep going and never return a 1.
However, your program still does not appear to return the correct result. You can split the piece of your code that finds the minimum element and replace it with this for cleanliness:
int least(int a[], int size){
int minPos = 0;
for(int i=0; i<size ;i++){
if (a[i] < a[minPos] ){
minPos = i;
}
}
return minPos;
}
Then you can call it by saying j = least(a, 20);. I will leave further work on your program to you. Consider calling your variables something meaningful instead of i,j,k,a,b.
Your equl function is using array indices from 0-20, but the arrays only have 1-19
j in lcm() is uninitialized if the first element is the smallest. It should be set to 0 at the top of the while loop
In the following code, when i=19, you are accessing a[20], which is out of the bounds of the array. Should be for(i=0;i<19;i++)
for(i=0;i<20;i++) {
if(a[i+1]<k)
You are not actually using the std namespace for the cout. this should be std::cout<<l
Your are including iostream.h. The standard is iostream without the .h, this may not work on such an old compiler tho
instead of hard-coding 20 everywhere, you should use a #define. This is not an error, just a style thing.
The following code does nothing. This is the default behavior
else
continue;