I want to have an array with initial size 4. The user can add as many elements(int type) to it. The function append() will be used for it. Also every time the size of the array is insufficient the same function will double its size and add the element to it.
#include <iostream>
using namespace std;
int n = 4;
int count = 0;
void append(int *a, int k)
{
if(count == n)
{
n *= 2;
int *b = new int[n];
for(int i = 0; i < count; ++i)
{
b[i] = a[i];
}
a = b;
}
a[count] = k;
++count;
}
void display(int *a)
{
for(int i = 0; i < count; ++i)
cout << a[i] << endl;
}
int main()
{
int *array = new int[n];
char t = 'y';
int num;
while(t != 'n')
{
cout << "Enter Value: ";
cin >> num;
append(array, num);
cout << "Do you want to enter more values?(y/n): ";
cin >> t;
}
cout << "The values entered are:\n";
display(array);
return 0;
}
After giving the following values for entering into the array:
1
2
3
4
5
6
7
8
8
9
10
11
12
13
15
I am getting the following output(using display() function)
1
2
3
4
0 [(This value depends on the compiler) #Erroneous Output]
6
7
8
1 [(This value depends on the compiler) #Erroneous Output]
10
11
12
13
14
15
I do not know why I am getting random values for the elements entered just after the array is updated(size is doubled), and how I should fix it.
Vectors, in essence are just dynamically allocated arrays. My question here is why not just use a vector with 4 slots initially. std::vector<int>(4); will do the trick although if you are adamant on remaking the vector class, research the topic of dynamic arrays and create a c++ template class based off them. According to my understanding .append() deallocates all elements in the vector, then reallocates them with the extra element at the end.
There are many articles online created by people trying to accomplish similar tasks, just do a little bit of digging around:
http://www.gamedev.net/topic/528822-c-writing-my-own-vector-class/
https://codereview.stackexchange.com/questions/50975/creating-a-custom-vector-class
Related
I have a variable k of type int to set the length of a dynamically allocated int array:
int *Numbers = new int[k];
But because of this I cannot iterate over the array, I get an error:
"no matching begin function was found required for this range-based for statement"
I also cannot get the length of the array using size();
Here's the complete code:
#include <iostream>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
int *Numbers = new int[k];
for (int i : Numbers) {// (There is a error)
}
for (int i = 0; i < size(Numbers); i++) {
}
}
Prefer using a std::vector instead of a std::array. (Like #tadman mentioned.)
Here is your code using std::vector instead:
#include <iostream>
#include <vector>
int main()
{
int b, k;
std::cin >> b >> k;
std::vector<int> Numbers(b,k); // Fills the vector "Numbers" with nth number of elements with each element as a copy of val.
for (int i : Numbers)
std::cout << i << std::endl;
for (int i = 0; i < Numbers.size(); i++)
std::cout << Numbers[i] << std::endl;
return 0;
}
Say I want 10 elements with the number 5.
Output:
10
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
Also consider not using namespace std;.
The simple and recommended solution is to use std::vector, however if you really want a dynamically allocated array and to use iterator like features on it, you can use iterator_range from boost library, which allows you to create an iterator range for it thus making it usable in range based for loops and in functions like std::size.
Live demo
#include <iostream>
#include<boost/range.hpp>
int main()
{
int k = 5;
int *Numbers = new int[k]{1,4,5,7,8};
auto arr = boost::make_iterator_range(Numbers, Numbers + k);
for (int i : arr) { //range based loop
std::cout << i << " ";
}
std::cout << std::endl << "Size: " << arr.size(); //print size
//or std::size(arr);
}
Output:
1 4 5 7 8
Size: 5
Range-based for loops work with arrays, but not work with pointers. The Actual issue is that arrays is actually a pointer and not an array.try to use simple array.
Using pointers is problematic for many reasons. The simple solution to your problem is to use a vector
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
vector<int> Numbers(k);
for (int i : Numbers) {
cout << i << endl;
}
for (int i = 0; i < Numbers.size(); i++) {
cout << Numbers[i] << endl;
}
}
C array does not have default iterator and thus there is no begin() and end() functions that are used to iterate over array when you use statment like this:
for (int i : Numbers)
You can check range-for reference:
range_expression - any expression that represents a suitable sequence (either an array or an object for which begin and end member functions or free functions are defined, see below) or a braced-init-list.
Okay, so since the dynamic array does not have a default iterator, do not use the for-each loop, instead consider using the regular for loop.
Also, mind the the size function will not work for an array (or dynamic array) and you need to remember the size, since it's not possible to get the size from the pointer only. Hence, this code would work:
#include <iostream>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
int *Numbers = new int[k];
const int SIZE = k;
for (int i = 0; i < SIZE; i++) {
cout << i << ' ';
}
}
You need to dereference *Numbers by using the * if you want to iterate over the array because *Numbers is a pointer to an integer which points to the first element of your array.For Example :
#include <iostream>
using namespace std;
int main()
{
int k = 10;
int *numbers = new int[k];
//filling the array
for(int i = 0 ; i < k ; ++i) {
*(numbers + i) = i ;
}
//output array element
for(int i = 0 ; i < k ; ++i) {
cout << numbers + i << " is the address of "<<*(numbers + i) << endl;
}
return 0;
}
The output is :
0x6f1750 is the address of 0
0x6f1754 is the address of 1
0x6f1758 is the address of 2
0x6f175c is the address of 3
0x6f1760 is the address of 4
0x6f1764 is the address of 5
0x6f1768 is the address of 6
0x6f176c is the address of 7
0x6f1770 is the address of 8
0x6f1774 is the address of 9
Unfortunatly, you can't get the size of your array with *Numbers because it's not an array but a pointer.
The question is:
"Write and test the following function that removes items from an array:
void removeAll(float a[], int& n, float x);
The function removes all occurrences of x among the first n elements of the array and decreases the value of n by the number removed.
I have written a code and it works perfectly fine. Basically, I tagged the value whose occurrences the user wants to remove with Zero and the code skips printing when it encounters zero. Basically we are not removing that value from the array just replacing it with some other value. What if the user entered zero in the array? then the other zeroes will also be skipped which I don't want them too. how can I do this?
Here is my code:
Don't use any classes, objects, vectors, strings nor any function in c++ which is like array.splice in js.
#include<iostream>
using namespace std;
void removeAll(float a[], int &n, float x)
{
for (int i = 0; i < n; i++)
{
if (a[i] == x)
{
a[i] = 0;
}
}
for (int i = 0; i < 10; i++)
{
if (a[i]!=0)
cout << a[i] << endl;
}
}
int main()
{
float a[10], x;
int n;
cout << "Enter values in array: \n";
for (int i = 0; i < 10; i++)
{
cin >> a[i];
}
cout << "Enter the value whose occurrence you want to remove from the array: ";
cin >> x;
cout << "Enter serial no. uptill which you want to remove the occurences";
cin >> n;
removeAll(a, n, x);
}
If you just want to print out the array without a chosen variable you can do it with one condition:
void removeAll(float a[], int &n, float x)
{
for (int i = 0; i < n; i++)
{
if (a[i] == x)
{
// Don't print it
}
else
{
cout << a[i] << endl;
}
}
}
If you want to eliminate the occurrences I would suggest to move the following numbers forward. I won't code it but here is an example:
array: 2,3,4,5,3,7
number to remove: 3
1. Iterate through the array and find '3'
2. If you find one, move all elements on the right side on step to left:
2 3 4 5 3 7 => 2 4 5 3 7 X
^
2 4 5 3 7 X => 2 4 5 7 X X
^
3. Count how many times you have done step two and return the new length/new array
To accomplish this you'll need to do 4 things:
Make a copy of n to hold the number of elements to iterate over: int size = n
Change your loop condition to consider this new element rather than n: i < size
Decrement n each time you replace a value in the nested if-statement
Remove the second for-loop (if you want to print out everything under n but the replaced numbers do that in an else-condition.)
Maybe I'm just confusing things a little bit.. But please consider this piece of C++ code:
#include <iostream>
#include <list>
using namespace std;
void printArray(int *arr, int n)
{
for(int i=0; i<n; ++i)
cout << arr[i] << " ";
cout << endl;
}
int main()
{
list<int*> arrays;
int times=20, v[9]={1,2,3,4,5,6,7,8,0};
arrays.push_back(v);
while(times--)
{
int *cur = arrays.front();
arrays.pop_front();
printArray(cur, 9);
int ta[9], tb[9];
for(int i=0; i<9; ++i)
{
ta[i] = *(cur+i)+1;
tb[i] = *(cur+i)-1;
}
arrays.push_back(&ta[0]);
arrays.push_back(&tb[0]);
}
return 0;
}
As you can see, the objective is to, beggining with a default array {1,2,3,4,5,6,7,8,0}, store (in times iterations) 2 variants of this array in a list of int pointers.
So, in the first iteration the 2 arrays {2,3,4,5,6,7,8,9,1} and {0,2,3,
,5,6,7,-1} should be stored in the list and thus, the first 3 printArray should be:
1 2 3 4 5 6 7 8 0
2 3 4 5 6 7 8 9 1
0 1 2 3 4 5 6 7 -1
Now, whats happening is that the first 3 printArray are:
1 2 3 4 5 6 7 8 0
2 3 4 5 6 7 8 9 1
2 3 4 5 6 7 8 9 1
I've already printed ta and tb at each iteration and I know that what's really being printed out is 1) default array, 2) first ta, 3) tb of the first ta. But I don't really know what's the reason for this behavior, I mean, aren't ta and tb new arrays (independent from the previous ones) in each iteration? If this is the case, my for is just assigning values for the new arrays positions, so why are they conflicting with each other?
The problem is quite simple, actually.
As #quimnuss stated in the comments, ta and tb were deallocating at some point and thus, the pointers saved in the list would point to something completely different from those arrays that were deallocated, leading to and undefined behavior of the program.
This statement makes complete sense since ta and tb are local variables of the while loop and so their validity will run out at each iteration completion.
We can workaround this problem by dynamically allocate memory at each iteration, like:
int *ta = new int[9];
int *tb = new int[9];
This away no loss of information will happen at every iteration end since the scope of this arrays are no longer local to the while loop.
Final code:
#include <iostream>
#include <list>
using namespace std;
void printArray(int *arr, int n)
{
for(int i=0; i<n; ++i)
cout << arr[i] << " ";
cout << endl;
}
int main()
{
list<int*> arrays;
int times=20;
int *v = new int[9];
for(int i=0; i<8; ++i)
v[i] = i+1;
v[8] = 0;
arrays.push_back(v);
while(times--)
{
int *cur = arrays.front();
arrays.pop_front();
printArray(cur, 9);
int *ta = new int[9];
int *tb = new int[9];
for(int i=0; i<9; ++i)
{
ta[i] = *(cur+i)+1;
tb[i] = *(cur+i)-1;
}
arrays.push_back(ta);
arrays.push_back(tb);
delete[] cur;
}
while(!arrays.empty())
{
int *p = arrays.front();
arrays.pop_front();
delete[] p;
}
return 0;
}
#include <iostream>
#include <algorithm>
bool wayToSort(int i, int j) { return i > j; }
bool wayToSortAlt(int i, int j) { return i < j; }
int main()
{
using namespace std;
int size = 5;
int *myArray = new int[size] { 0 };
int option = 0;
cout << "How many numbers do you want to enter?: ";
cin >> size;
cout << "How do you want to sort? ( [1] Greatest [2] Lowest ): ";
cin >> option;
cout << "----\n";
// Get number inputs
for (int count = 0; count < size; ++count)
{
cout << "Enter a number: ";
cin >> myArray[count];
}
cout << "----\nSorted:\n----\n";
// Sort for highest numbers
if (option == 1)
sort(myArray, myArray + size, wayToSort);
else
sort(myArray, myArray + size, wayToSortAlt);
// Print each number
for (int count = 0; count < size; ++count)
{
cout << myArray[count] << "\n";
}
delete[] myArray; // Clean up
myArray = nullptr; //
return 0;
}
I run this code in Visual Community 2013 and if I input a high number such as 10, I get a heap corruption error. From what I have read, the heap corruption error happens when you try to write to an unallocated memory adress, but I don't understand two things:
1) Why does this happen with a dynamic array, and
2) Why does the error only happen when I try to put in a larger number.
Luke,
You have defined the size of the array already. So it is not a dynamic array. It is a pointer to an array that has a size of 5 and can hence only store up to 5 ints.
So you basically have allocated enough space to hold 5 int. This means that if you try to store more than 5, for example the 6th int at index of 5, you are trying to access memory that is not yours to claim.
for example here you have:
[] [] [] [] []
1 2 3 4 5
is good
[] [] [] [] []
1 2 3 4 5 6 7 8 ...
cause the heap corruption.
Might I suggest std::vector ?
The problem that I am working on right now is here, but I am of course not looking for the complete answer to this homework problem. All I am asking for is the steps in the final parts of the question. This is what I have so far:
int main()
{
cout << "Please enter the number of guests attending your party: ";
int k;
cin >> k;
cout << "Please enter the number of rounds of removal you'd like to perform: ";
int m;
cin >> m;
for (int i = 1; i <= m; i++) {
cout << "Please enter the multiple at which you'd like the removal to be at for round " << i << ": ";
int r;
cin >> r;
if (k % r == 0) {
k - r;
}
cout << k << endl;
}
system("pause");
}
This is all so confusing to me, and I truly have no idea where to turn to get answers. It seems like I'd need an array to solve this, but arrays in C++ cannot be variable, and the array length would be k, a variable input. Any help would be very appreciated.
I've read that question. you need a dynamic list like Linked list because you need to put and remove different items from different index so using arrays will be difficult.
Try to use std::vector or std::list, you can add or remove any any of list
#include <list>
std::list<int> mylist;
How can you add and remove values from list, check this link http://en.cppreference.com/w/cpp/container/list
For using your own Linklist, check this link How could i create a list in c++?
According to your question an std::vector will be the best choice because it is a combination of an array & linked list in raw terms or we can simply say it's a dynamic array.
However as you mentioned n your comment that you haven't been taught anything other than basic arrays & want a solution within whatever you have learnt, then you have to take an array. Now the problem is that arrays are static & you cannot delete elements from it. So all you can do is to keep a counter that will take care of the number of elements in it.
// array insert and delete
#include <iostream>
using namespace std;
void see_array (int a[], int f, int b)
{
for (int i=f; i<b; ++i)
cout << a[i] << ' ';
cout << '\n';
}
int get_pos (int a[], int f, int b, int num)
{
for (int i=f; i<b; ++i)
{
if (a[i] == num)
return i;
}
return -1; // if search is unsuccessful
}
int main()
{
int a[] = {1,2,3,4,5,6,7,8,9,10};
int front = 0, back = 10; // as we have 10 elements
// delete last element
--back;
see_array(a, front, back);
// delete first element
++front;
see_array(a, front, back);
// delete element from middle say 6
int pos = get_pos(a, front, back, 6);
if (pos != -1)
{
for (int i = pos; i<back; ++i) // shift elements towards left
{
a[i] = a[i+1];
}
--back; // decrease size of the array
see_array(a, front, back);
}
return 0;
}
/* Output :-
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9
2 3 4 5 7 8 9
*/
I hope the above program is of some help to you !!! Good luck !!!