I've realised Fenwick Tree, but when i try to find sum on segment there is Segmentation Fault 11.
#include <vector>
#include <iostream>
using namespace std;
class Fenwick{
public:
Fenwick();
int sum(int l, int r);
void update(int pos, int value);
void print(int i);
private:
vector<int> fentr;
int sum(int i);
};
Fenwick::Fenwick(){
}
void Fenwick::print(int i){
cout<<fentr[i];
}
int Fenwick::sum(int l, int r){
return sum(r)-sum(l-1);
}
int Fenwick::sum(int i){
int result=0;
// while(i>=0){
// result+=fentr[i];
// i=(i&(i+1))-1;
// }
for(int j=i; j>=0; j=(i&(i+1))-1){
result+=fentr[j];
}
return result;
}
void Fenwick::update(int pos, int value){
while (pos<fentr.size()){
fentr[pos]+=value;
pos=pos | (pos+1);
}
}
int main(){
Fenwick a;
a.update(0, 1);
a.update(1, 2);
a.update(2, 3);
a.update(3, 4);
a.update(4, 5);
int j = a.sum(0,2);
cout<<j;
}
Also, have i done it right? I mean, i completely understood idea of Fenwick tree, I just can't find out what we must do with initial array? May be i need to pass as an argument to Fenwik class and then working with him? Or just a lot of updates? Thank you in advance.
As far as I can see, you haven't initialized the fentr vector. This won't fail on update, since you're looping to fentr.size(), but it will segfault on the call to sum.
Related
I implemented binary search in two ways and wondering which is more efficient? please help me know which is more efficient and how can it further be optimized? is time complexity remains same in both approach? I am a beginner in programming.
approach 1;
#include<iostream>
using namespace std;
bool BinarySearch(int*a,int n,int s ){
if(n==1){
if(a[0]==s)
return true;
else
return false;
}
else{
if(s<a[n/2]){
int U[n/2];
for(int i=0;i<n/2;i++){
U[i]=a[i];
}
return BinarySearch(U,n/2,s);
}
else{
int V[n-n/2];
for(int i=0;i<n-n/2;i++){
V[i]=a[i+n/2];
}
return BinarySearch(V,n-n/2,s);
}
}
}
int main(){
int array[10]={2,4,6,8,10,12,14,16,18,22};
cout<<BinarySearch(array,10,9);
}
approach 2:
#include<iostream>
using namespace std;
bool Bsearch(int arr[],int s,int l,int x){
cout<<"calling bsearch with arguments "<<s<<' '<<l<<' '<<x<<endl;
if(l==1)
return arr[s]==x;
int h=l/2;
if(x<arr[s+h])
return Bsearch(arr,s,h,x);
else
return Bsearch(arr,s+h,l-h,x);
}
int main(){
int marks[11]={17,18,20,22,24,26,28,30,32,34,36};
cout<<Bsearch(marks,0,11,32);
}
Thanks in advance for the kind help.
Other posters are correct that variable-length arrays are not good C++. If you define your main() as:
int main() {
std::array<int> marks{17,18,20,22,24,26,28,30,32,34,36};
cout<<Bsearch(marks,0,32);
}
or:
int main() {
std::vector<int> marks{17,18,20,22,24,26,28,30,32,34,36};
cout<<Bsearch(marks,0,32);
}
then you can drop the pointer/length pair in the parameter list to your binary-search function. The function prototype becomes something like:
bool Bsearch(const std::array<int>& arr, int s, int x);
I searched for a lot of resources on C++ and arrays. I learned that arrays act like pointers in c++ and I am confused on how to create a multi-dimensional array and assigning value to indexes. I usually code in Java and Python but know I am working with an Arduino and I need to learn c++.
My Arduino(c++) code regarding about this array is:
#include "Arduino.h"
#include "cell.h"
#include <cell.h>
cell maze[16][16];
cell * current = new cell(1, 1, 0, false, 0);
cell * end_pt = new cell(1,1,1,true);
maze[15][15] = end_pt;
My .h and .cpp files;
#include "Arduino.h"
#include "cell.h"
#include "Arduino.h"
cell::cell(){
right = 0;
}
cell::cell(int r, int l, int f, bool inf){
right = r;
left = l;
forw = f;
info = inf;
value = 70;
printf("%d\n", right);
printf("%d\n", left);
printf("%d\n", forw);
printf("%d\n", inf);
printf("%d\n", val);
}
cell::cell(int r, int l, int f, bool inf, int val){
right = r;
left = l;
forw = f;
info = inf;
value = val;
printf("%d\n", right);
printf("%d\n", left);
printf("%d\n", forw);
printf("%d\n", inf);
printf("%d\n", val);
}
void cell::setR(int r){
right = r;
}
void cell::setL(int l){
left = l;
}
void cell::setF(int f){
forw = f;
}
void cell::setI(bool inf){
info = inf;
}
void cell::setV(int val){
value = val;
}
int cell::getR(){
return right;
}
int cell::getL(){
return left;
}
int cell::getF(){
return forw;
}
bool cell::getI(){
return info;
}
int cell::getV(){
return value;
}
#ifndef cell_h
#define cell_h
#include "Arduino.h"
class cell{
public:
cell();
cell(int r, int l, int f, bool info);
cell(int r, int l, int f, bool info, int val);
void setR(int r);
void setL(int l);
void setF(int f);
void setI(bool inf);
void setV(int val);
int getR();
int getL();
int getF();
bool getI();
int getV();
private:
int right;
int left;
int forw;
bool info;
int value;
};
#endif
'maze' does not name a type is my error. Please help and thank you in advance!
There's a problem with this line:
maze[15][15] = end_pt;
maze[15][15], and any other object in maze, is of type cell
end_pt is of type cell*
This means you are trying to assign two different types.
Instead, do this:
cell end = cell(1,1,1,true);
maze[15][15] = end;
or just
maze[15][15] = cell(1,1,1,true);
Since you are using C++, consider looking into std::array instead. And avoid new/delete when possible.
'maze' does not name a type
In fact, 'maze' DOES NOT name a type. It is, indeed, an object.
In other languages you can write instructions outside the functions, since the whole file body is considered a "function". In C, however, outside functions you can only write declarations and definitions of global variables. You should have written:
#include "Arduino.h"
#include "cell.h"
#include <cell.h>
cell maze[16][16];
cell * current = new cell(1, 1, 0, false, 0);
cell * end_pt = new cell(1,1,1,true);
void setup()
{
maze[15][15] = end_pt;
}
Now, as the other answer pointed out, you can't assign a pointer to the value. If you want to keep maze as a cell matrix, you have to copy the values hand by hand:
void copyCell(cell *dst, cell src)
{
dst->right = src.right;
dst->left = src.left;
dst->forw = src.forw;
dst->info = src.info;
dst->value = src.value;
}
void setup()
{
copyCell(&(maze[15][15]), end_pt);
}
(or better just include a copy function in the class)
OR declare maze as a cell pointers matrix:
cell *maze[16][16];
This depends on how you want to implement the program
I'm trying to solve a challenge question of summing all primes under 2 million. Knowing full well a naive approach would take too long, I decided to implement The Sieve of Eratosthenes with a counter to record the sum. It works for up to 512500 after which I receive this error:
Is the input size just too big for code to handle? If that's the case, how can I improve my code to avoid this error. If that's not possible, what is a better algorithm to implement for these purposes?
Here is my header code:
#ifndef NUMBERSIEVE_H
#define NUMBERSIEVE_H
class NumberSieve
{
public:
NumberSieve();
virtual ~NumberSieve();
int EratosthenesSieve(int num);
private:
void SetSieve(int nums[],int Size);
int current_prime;
int current_prime_address;
void updateSieve(int nums[],int Size,int start);
bool updateCurrentPrime(int nums[],int Size,int start);
bool notComplete;
void printSieve(int nums[],int Size);
int primeSum;
};
#endif // NUMBERSIEVE_H
Here is my implementation file:
#include "NumberSieve.h"
#include <cstdlib>
#include <iostream>
NumberSieve::NumberSieve()
{
//ctor
}
NumberSieve::~NumberSieve()
{
//dtor
}
void NumberSieve::SetSieve(int nums[],int Size)
{
for(int i=0;i<Size;i++)
{
nums[i]=(i+1);
}
nums[0]=0;//Sets the first composite number 1 to 0. We use 0 as an analogy for "crossing out numbers in the Sieve".
}
void NumberSieve::updateSieve(int nums[],int Size,int start)
{
int CURRENT_PRIME=nums[start];
for(int i=start;i<Size;i++)
{
if(nums[i]%CURRENT_PRIME==0)
{
nums[i]=0;
}
}
nums[start]=CURRENT_PRIME;
}
bool NumberSieve::updateCurrentPrime(int nums[],int Size,int start)
{
for(int i=start+1;i<Size;i++)
{
if(nums[i]!=0)
{
primeSum+=nums[i];
current_prime=nums[i];
current_prime_address=i;
return true;
}
}
return false;
}
void NumberSieve::printSieve(int nums[],int Size)
{
for(int i=0;i<Size;i++)
{
std::cout<<nums[i]<<std::endl;
}
}
int NumberSieve::EratosthenesSieve(int num)
{
int Eratosthenes[num];
int primeSum=0;
SetSieve(Eratosthenes,num);
current_prime=2;
primeSum+=2;
current_prime_address=1;
updateSieve(Eratosthenes,num,current_prime_address);
notComplete=updateCurrentPrime(Eratosthenes,num,current_prime_address);
while(notComplete)
{
updateSieve(Eratosthenes,num,current_prime_address);
notComplete=updateCurrentPrime(Eratosthenes,num,current_prime_address);
}
return primeSum;
}
My best guess is stackoverflow, because of this:
int Eratosthenes[num];
Instead try getting it from the free store:
int* Eratosthenes = new int[num]
Update the rest of the code accordingly
If you are not comfortable with pointers, a vector might be another option.
I was working on this code for a project on school and when I wanted to try debugging my code just got segmentation fault before even running the first line in main() so i was wondering if i miss something on my code or is the compiler's fault.
#include <iostream>
using namespace std;
class poly
{
public: int a[1000000];
private:
int forx(int x);
public:
poly(){cout<<"add";}
~poly(){cout<<"kill";}
void add();
void sum(int *x,int *y);
void dif(int *x,int *y);
void mult(int *x,int *y);
void renew();
};
void poly::add()
{
int i,n;
cin>>n;
a[0]=n;
for (i=1; i<=n; i++)
{
cin>>a[i];
}
}
int poly::forx(int x)
{
int s,i,p;
p=1;
for (i=1; i<=a[0]; i++)
{
s+=p*a[i];
p*=x;
}
return s;
}
void poly::sum(int *x,int *y)
{
int i,m=x[0]>y[0]?x[0]:y[0];
a[0]=m;
for (i=1; i<=a[0]; i++)
{
a[i]=x[i]+y[i];
}
}
void poly::dif(int *x,int *y)
{
int i,m=x[0]>y[0]?x[0]:y[0];
a[0]=m;
for (i=1; i<=a[0]; i++)
{
a[i]=x[i]-y[i];
}
for (i=a[0]; i>0; i--)
{
if (a[i]!=0) break;
a[0]--;
}
}
void poly::mult(int *x,int *y)
{
int i,j,k;
for (i=1; i<=(x[0]+y[0]-2); i++)
{
j=0;
k=y[0]-1;
while (j+k!=i)
{
if (j+k>i) k--;
if (j+k<i) j++;
}
while (j<x[0] && k>=0)
{
a[i]+=x[j]*y[k];
k--;
j++;
}
}
}
void poly::renew () {
int i;
for (i=1; i<=a[0]; i++)
{
cout<<a[i];
}
}
int main()
{
cout<<"starting";
poly w;
w.add();
poly h;
h.add();
poly o;
o.sum(w.a,h.a);
o.renew();
o.dif(w.a,h.a);
o.renew();
o.mult(w.a,h.a);
o.renew();
}
Becase of int a[1000000];, size of poly class is very large. Making a (actually you are making 3) local variable(s) of this class (on stack) would give you segmentation fault.
You can try making them static or move them to global scope or alloc them dynamically.
...
static poly w;
w.add();
static poly h;
h.add();
static poly o;
...
Another solution is to replace arrays with std::vector
change public: int a[1000000]; to
...
public: std::vector<int> a;
...
poly() : a(1000000) {cout<<"add";}
...
Now you can create local objects of this class.
Another related question Segmentation fault on large array sizes
here is implementation IntSetList in c++
#include <iostream>
using namespace std;
class IntSetList{
private:
int n;
struct node{
int val;
node *next;
node(int v,node *p){val=v;next=p;}
};
node *head,*sentinel;
node *rinsert(node *p,int t){
if (p->val<t){
p->next=rinsert(p->next,t);
}
else if (p->val>t){
p=new node(t,p);
n++;
}
return p;
}
public:
IntSetList(int maxelens,int maxval){
sentinel=head=new node(maxval,0);
n=0;
}
int size() { return n;}
void insert(int t){ head=rinsert(head,t);}
void report(int *v){
int j=0;
for (node *p=head;p!=sentinel;p=p->next)
v[j++]=p->val;
}
void display (int *v){
for (int i=0;i<sizeof(v)/sizeof(v[0]);i++){
cout<<v[i];
}
}
};
int main(){
IntSetList s(10,15);
int v[10];
s.insert(7);
s.insert(2);
s.insert(1);
s.insert(11);
s.insert(13);
s.insert(14);
s.insert(5);
s.insert(6);
s.insert(12);
s.insert(9);
s.report(v);
s.display(v);
return 0;
}
but it does not show me any output of course there is c++ standart library but i need to implement myself so i am making practises please help what is wrong?
No output at all? I suspect that it is outputting at least one number, since sizeof(v) is at least as big as sizeof(v[0]), but probably only just as big, since a pointer is the same size as an int on most 32-bit computers.
The sizeof(v)/sizeof(v[0]) trick only work on arrays, not pointers. A common trick to get around this is to declare the function as a template, thus:
template <int N>
void display (int (&v)[N])
{
for (int i = 0; i < N; ++i)
{
cout << v[i];
}
}
A more conventional solution is to pass the length explicitly:
void display (int *v, int n)
{
for (int i = 0; i < n; ++i)
{
cout << v[i];
}
}
A couple of points to note:
This will mash all the numbers together because you haven't put any whitespace in between them.
The display function doesn't have to be a member of IntSetList, since it doesn't interact with the class at all.
The simplest solution, BTW, is to not write the function at all:
std::copy(v, v + sizeof(v)/sizeof(v[0]), std::ostream_iterator<int>(std::cout));