Following is my code which doesnot properly bubbles up the larger value .Can any one help out .The problem is somewhat at count++ .
#include<iostream>
using namespace std;
class heap{
public:
int count;
heap(int c)
{
count=c;
}
int Arr[10];
void insert(int num);
void deletemax();
void print();
};
void heap::insert(int num){
if(count==10){
cout<<"Heap full\n";
exit(1);
}
else{
Arr[count]=num;
count++; //The real problem arises here that the compiler adds 1 to count and when the code moves ahead it sets position var to count++ value and tries to compare a value at Arr[POS] with its parent whereas there is no value at this place set uptill.
}
int POS=count;
while(Arr[POS]>Arr[(POS-1)/2]){
int temp;
temp=Arr[POS];
Arr[(POS-1)/2]=temp;
POS=(POS-1)/2;
}
}
void heap::print(){
for(int i=0; i<10; i++){
cout<<Arr[i]<<endl;
}
}
int main(){
heap h(0);
int a;
int b=0;
while(b<10){
cout<<"Insert node in heap\n";
cin>>a;
h.insert(a);
b++;
}
h.print();
return 0;
}
I would agree, that's where your problem is.
There are many issues with the code you posted, some of which include:
As to your specific issue, I would guess you need to change the line in heap::insert() to "int POS=count-1;" to properly start iterating from the back of the array.
You need to consider the case of adding an element to an empty array and what then happens in your sorting code.
Your constructor allows someone to create a heap that will overflow the fixed sized array, for example heap(1000). In addition, the Arr member is not initialized which means it has undefined data for any value but heap(0). In this case your constructor should not take any parameters and count should just be initialized to 0.
The purpose of the code is confusing. Is it a heap, a sorted array, an attempt to approximate a heap with an array, none of the above? If you are simply trying to implement a fixed sized sorted array then I believe your sorting code in insert() will not work (e.g., consider adding 100 to a heap containing [1,2,3]).
There are other, more basic things, wrong (like not using any the STL containers, public class member, non-const parameter passing, "using std", etc...) but I'm assuming you are merely experimenting/playing here.
Related
#include <iostream>
#include <vector>
using namespace std;
class Stack{
public:
vector<string> vc;
int length=0;
void peek(){
if(vc.size()==0){
cout<< "The stack is empty"<<endl;
}
cout<< vc[length]<<endl; //----> does not work;
//cout<<vc[vc.size()-1]; ---> does not work either
//cout<<vc.end(); ----> does not work either;
}
void add(string value){
vc.push_back(value);
length++;
}
void pop(){
vc.erase(vc.end());
length--;
}
void show(){
for (int i=0;i<vc.size();i++){
cout << vc[i] << " ";
}
cout<<endl;
}
};
int main()
{
Stack mystack;
mystack.peek();
mystack.add("Hello");
mystack.peek();
mystack.add("frands");
mystack.add("chai");
mystack.add("pee");
mystack.add("lo");
mystack.show();
mystack.peek();
mystack.pop();
mystack.show();
}
problem 1->
the problem arises in the peek() function i cannot access the last element in my vector space i get returned with a segmentation fault(core dump) error.
problem 2->
and while pasting this code on stack overflow i had to manually add 4spaces in each code line how to do this at one step (sorry for a silly question).
There are a few problems in your code:
void peek(){
if(vc.size()==0){
cout<< "The stack is empty"<<endl;
}
cout<< vc[length]<<endl; //----> does not work;
}
If vc.size() == 0, you print out a message, and then proceed to index into the empty vector. You should return inside that if, to avoid looking at an invalid index.
Below it you use use a length variable, which I presume is the acting the role of the vector's size(). EITHER you need to ensure the vector's size is the same as the stack's logical size (and then you don't need a length variable), OR you should be testing if length == 0, and not looking at size() here. Otherwise, you could have a positive size of vector, and a length of zero, and what's logically empty may print junk values.
Another serious mistake, your pop function:
void pop(){
vc.erase(vc.end()); // <<< MISTAKE
length--;
}
This is erasing the "end" element, which is not a valid position to erase. Remember, end denotes the first place after the last valid element in the vector, so your code yields undefined behavior. You should use the vector function pop_back instead, as it does precisely what you want. It also will reduce the size of the vector, meaning you don't need a length variable at all! Instead you can use the vector's size().
Next, in peek():
cout<< vc[length]<<endl;
When a vector contains N things, they are indexed from 0..(N-1). Using the number of elements will go too far into the vector. Instead, use length-1 (or vc.size()-1 after fixing pop()). However, you can use vc.back() to access the last element without any need to compute its offset.
help me to find out minimum value from the array in function4. I am getting 0 every time. Sometimes I get the value present at first index of the array as minimum value. Kindly review my code and help me to solve the problem.
#include <iostream>
using namespace std;
int count=0;
void function1(int a[]) {
for (count=0;count<100;count++) {
cin >> a[count];
if (a[count]==0)
break; }
}
int function2 (int a[]) {
int sum=0,avg=0;
for (int n=0;n<count;n++) {
sum=sum+a[n]; }
avg=sum/count;
return avg;
}
//maximum value
int function3 (int a[]) {
int max1=a[0];
for (int count=0;count<100;count++) {
if (a[count]>max1)
max1=a[count];
}
return max1;
}
//minimum value
int function4 (int a[]) {
int min1=a[0];
for (int count=0;count<100;count++) {
if (a[count]<min1){
min1=a[count];}
}
return min1;
}
int main () {
int a[100]={0};
function1(a);
cout <<"Average is : "<<function2(a)<<'\n';
cout <<"Maximum Value is : "<<function3(a) <<'\n';
cout <<"Minimum value is : "<<function4(a) << '\n';
}
It looks like you are trying to learn programming itself, and not only C++.
If you were to look how C++ gets the smaller element in a container, I'd advise you to look into STL documentation std::min_element().
This has been asked here before: How to find minimum value from vector?
But surely you still need a few hints before:
Name your functions intuitively. function4 is a terrible name for a function whose meaning is to find the lowest/smallest/minimum value in a container. How about calling it minimum?
Allways search before posting. StackOverflow is smart enough to search for you while you type.
The way you pass your array to your functions is a problem. You have a function that makes assumptions on array size with no guaranties. If you simply change your declaration from a[100] to a[10] your program will be accessing data outside array bounds.There are many solutions for it. Include an extra parameter telling the array size or use std::vector, for example.
1.Please study how parameters (specially arrays) can be passed in C++. Take a look at Passing arrays to and from functions safely and securely to begin.
IMPORTANT: Your data is being populated by function1() through console input. ** are you sure you are filling in 100 values in your array and none is ZERO? ** If you have any 0 in your array and no negative inputs, obviously the minimum value will be 0!
Maybe you can be confused with this line:
int a[100]={0}; // This initlizes the whole array to zero.
int a[100]={SOME_VAL}; // This initlizes the first element to SOME_VAL, and the rest of the array to zero.
So, probably the array has a lot of zeros, so you are getting the minimum.
But, you don't need to make this functions yourself, just use std::min_element
Example:
std::cout << "Minimum value is : " << *std::min_element(a,a+99) << std::endl;
So I am writing quite a long code and now I came to a problem. How to change structure's arrray's values and get them back to main function.
What I am trying to do this function is: to insert a new value at first array spot(which is 0). The whole for cycle frees the Z[0] and works fine. But I do not know how to return whole CHANGED structure array to the main program. How to do this?
Thank you.
P.S. sorry, for my broken english.
Here are the neccessary parts of the code:
void insertion(Player Z[], int size); //declaration of the funcion
...
int main()
{
int size=5;
Player *Z = new Player[size];
Insertion(Z, size); //calling the function
...
}
void Insertion(Player Z[], int size) //function
{
size++;
Player* temp = new Player[size];
for(int i=0;i<=size-1;i++)
{
temp[i+1]=Z[i];
}
delete [] Z;
Z = temp;
cin>>Z[0].name;
cin>>Z[0].surname;
}
I see many problems in your code.
For example, why are you allocating an array of 5 Players, then deallocating the array and allocating the array again, having the same size? What's the benefit?
You should also note that C++ has call-by-value semantics so the delete[] Z and Z = temp lines have no effect outside of the function you're calling. So, that function should have a signature void Insertion(Player **Z, int size); or Player *Insertion(Player *Z, int size) if you don't want to modify the argument in-place but instead return the new value.
The comments suggested using std::vector. I heavily recommend that approach. If you need a variable-sized container, std::vector is the best choice.
If you however have a reason to do the manual allocations yourself (such as homework assignment) you should use the following strategy: maintain the size of the array in addition to its capacity, and whenever the size would be greater than the capacity, allocate a new array with twice the capacity, copy the contents and deallocate the old array.
I am trying to create an array that generates random values, then assign a pointer to that array in order to use it in other functions.
Question 1: Is this the right approach?
Question 2: When I run the code below, my pointer function generates values inconsistent with what the actual array's value is. What am I doing wrong?
int size = 100;
int theray[size];
for(int i=0; i<size; i++)
{
theray[i] = (rand()%100);
}
//Output array
cout<<"The array: ";
for(int j=0; j<size; j++)
{
cout<<theray[j]<<" ";
}
cout<<endl;
int (*parray)[100] = &theray;
cout<<"The array pointer: ";
for(int k=0; k<size; k++)
{
cout<<*parray[k]<<" ";
}
Question 1: is this the right approach?
No. The right approach is to use std::vector<int> if size is not known at compile time1, and std::array<int, size> if it is2. There is no need for pointers here.
void foo(const std::vector<int>& v)
{
// do stuff with v
}
...
std::vector<int> v(size); // vector with size elements
// do something with v
// pass v to a function
foo(v);
Question 2: when I run the code below, my pointer function generates values inconsistent with what the actual array's value is. What am I doing wrong?
If you use C++ idioms you won't even encounter this problem, so I consider the question moot. However, in your case you have a problem of operator precedence: be explicit about applying de-reference * before access []:
cout<< (*parray)[k] << " ";
1 As shown in the example, you can use an std::vector as a fixed size array, where the size need not be known at runtime. Just bear in mind that it is possible to change it's size after construction.
2In your example, size is not a compile time constant so you cannot use std::array. However, if you had declared it as const int size = 100; then it would be considered a compile time constant.
Your code is a bit off in three ways. First, there is no need to use &theray. Array names already reference a memory address. You can simply assign the pointer to theray. Second, you're declaring an array of 100 pointers. Based on your description, it sounds like you just want one pointer that points to the array. Your declaration should just be int *parray instead of int *parray [100]. Finally, once you have a pointer to the array, you can access elements of the array the same way you would with the original array, only with the name of the pointer, instead of the name of the array. Try changing your last block of code (starting with the pointer declaration to this:
int *parray;
parray = theray;
cout<<"The array pointer: ";
for(int k=0; k<size; k++)
{
cout<<parray[k]<<" ";
}
Question 1
Is this the right approach?
Usually not. It depends on what you are trying to achieve.
For high level semantics you'd in most cases use std::vector<int> or, if the size is fixed and you are using C++11, std::array<int, size>. If you actually have to go down to the pointer level, you'd usually write it like this:
int *parray = theray;
cout<<"The array pointer: ";
for(int k=0; k<size; k++)
{
cout<<parray[k]<<" ";
}
This works because arrays will degrade to pointers, and the […] subscripts work on these pointers just like they work on the original arrays.
Question 2
When I run the code below, my pointer function generates values inconsistent with what the actual array's value is, what am I doing wrong?
*parray[k] gets interpreted as *(parray[k]) while you intend to use it as (*parray)[k].
Question 1: is this the right approach?
No. Use std::vector<> for arrays whose size can change dynamically (at run-time). Prefer avoiding pointers and manual memory management.
Question 2: when I run the code below, my pointer function generates values inconsistent with what the actual array's value is. What am I doing wrong?
First of all, the fact of creating pointers so you can pass the array to a function. This is not necessary. Here is how I would use classes from the C++ Standard Library to write that program (in C++11):
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
// Sample function that prints the vectors's content
void foo(std::vector<int> const& v)
{
copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, " "));
}
int main()
{
// Populate the vector...
size_t sz = 10;
std::vector<int> v(sz);
generate(begin(v), end(v), [] () { return rand() % 100; });
// Pass it to a function...
foo(v);
}
As I tried to solve this interview problem: find the sum of continuous element in an array which equals to a target number, so I come up with the following code. However, I really don't understand why it has some memory allocation problem. Here is the link to the full code. when I tried to insert the second element of currSum into the set and map, it will have some error message like "memory clobbered past end of allocated block". Isn't set, map dynamically allocated for insert? I really don't understand why it's not working as I think.
I also paste the full code here:
#include <map>
#include <set>
#include <iostream>
using namespace std;
void print_array(int arr[], int start, int end)
{
for(int i=start;i<=end;i++)
cout<<arr[i]<<" ";
cout<<endl;
}
//given an array, find the continous sum of the array which is a target number
void findTargetSum(int arr[], int target, int sizeArr)
{
map<int, int> valIdxMap;
set<int> prevSet;
int* currSum= new int(sizeArr+1);
currSum[0]=0;
for(int i=1;i<=sizeArr;i++)
{
currSum[i]=currSum[i-1]+arr[i-1];
}
//now the problem is to find two elements i, j in array currSum,where currSum[j]-currSum[i]=target && j>i
for(int i=0; i<=sizeArr;i++)
{
int tmp=currSum[i]-target;
set<int>::iterator iter=prevSet.find(tmp);
if (iter !=prevSet.end())
{
cout<<"located one range of array elements with sum to"<<target<<endl;
int startIdx=valIdxMap[*iter];
print_array(arr,startIdx,i-1);
}
else
{
prevSet.insert(currSum[i]);
valIdxMap.insert(make_pair(currSum[i],i));
}
}
delete currSum;
}
void testfindTargetSum()
{
int tst_arr[]={2,4,5,-1,3,8};
int target=11;
findTargetSum(tst_arr,11,6);
}
int main()
{
testfindTargetSum();
return 1;
}
The error is in this line:
int* currSum= new int(sizeArr+1);
That line acquires a single int and initializes it to the value sizeArr+1. You probably meant:
int* currSum= new int[sizeArr+1];
That will acquire a block of sizeArr+1 elements of type int. Additionally you will have to change the line delete currSum; to be delete [] currSum;.
My advice, on the other hand, would be not to manage memory manually but use a standard container, for example:
std::vector<int> currSum( sizeArr+1 );
Will basically be an in-place replacement for your current implementation and it will manage memory automatically.
As of the implementation, I believe that you can actually do it without any extra memory in O(N) by accumulating the start index, end index and sum of the values in three variables while iterating. While the accumulated value is smaller than the target, increment the end index and add the value. When the accumulated value grows higher than the target, increment the start index and decrement the accumulated value by that amount.
you wrote
int* currSum= new int(sizeArr+1);
you probably meant
int* currSum= new int[sizeArr+1];