How to delete one data line from a structure array ? (with index) - c++

I am trying to make a function, which deletes one line from a structure array, I give function the index of line I want to delete and the structure array. E.g. we have structure array :
Structure
{
string First;
string Second;
string Third;
string Fourth;
string Fifth;
}
Structure array :
Structure A[100];
int n;
So there are five string type elements in this structure array :
A[i].First A[i].Second A[i].Fourth A[i].Fifth // i is the index
Our function is like this :
void Delete(Structure A[], int index, int & n)
{
Structure t;
for (int i = index; i < n-1; i++)
{
t = A[i];
A[i] = A[i + 1];
A[i + 1] = t;
n--;
}
}
So I give function index and I want the function to delete all elements of my structure array with that index ( so how can I take like the whole "line" of those elements, instead of deleting them one by one ?)
A[index].First A[index].Second A[index].Third A[index].Fourth A[index].Fifth
The function however doesn't work. Can you give me some tips/advises/suggestions, please ? Thanks in advance.

At first level, your question is basically: how to remove a line from an array whose used size is stored in an external variable (passed here as n)
The signature of your function is correct, the implementation is not. It should be:
void Delete(Structure A[], int index, int & n)
{
// eventually control index >= 0 and index < n...
n -= 1;
for (int i = index; i < n; i++)
{
A[i] = A[i + 1];
}
}
If you have a recent version of C++ that support move semantics, you could speed up the operation by moving the strings instead of copying them:
n -= 1;
for (int i = index; i < n; i++)
{
A[i] = std::move(A[i + 1]);
}

Related

How do you remove an element from an array?

I'm new to c++ and I'm writing an array manipulator program. How would you write a function that removes an element from an array? What parameters would you pass to it? The function cannot have any cout or cin statements, they must be in main instead. How would you call the function? I wrote a function for adding an element to an array, and it looks like this:
int insertValue(int arr[], int value, int pos, int size)
if (size == 10)
cout << "Array full" << endl;
else
{
int i;
for (i = size - 1; i >= pos; --i) {
arr[i + 1] = arr[i];
}
arr[pos] = value;
++size;
}
cout << endl;
return size;
This function works when called. Would removing an element from an array and moving everything to the left follow the same layout? This is what I have so far for that function:
int removeValue(int arr[], int value, int pos, int size)
for (int i = pos; i < size; ++i) {
array[i] = array[i + 1];
}
arr[pos] = value;
return size;
I don't think I have the right idea for this code, which is why I am confused. Can someone explain the idea behind this function and how it would be written correctly?
Thanks for your help!
Use std::vector or std::array instead of c-array([]).
To remove elements from container, you should use std::vector + std::remove + std::vector::erase
This line is going to overflow the array, with all the attended horrors, as you are indexing one past the end.
array[i] = array[i + 1];
But other than that as long as you keep track of how many elements your array has it should be OK

insertion sort algorithm using a second array C++

Trying to understand the insertion sort algorithm..
My algorithm looks like this currently:
void insertionSort(int *array, int N) {
int value;
int hole;
int *array2;
for (int i = 1; i < N - 1; i++) {
value = array[i]; //next item to be inserted in array 2
hole = i;
while (hole > 0 && array[hole - 1] > value) {
array[hole] = array[hole - 1];
hole = hole - 1;
}
array[hole] = value;
}
}
My algorithm works for sorting arrays, however I now need to change it so that I build up a new sorted array (array2) one element at a time, rather than just working with the original array.
Is there a simple way to implement this given my completed algorithm?
Thanks.
You can use the following method:
int *array2 = calloc(N, sizeof(int));
for(var index = 0; index < N; index++)
{
array2[index] = array[index];
}
and after that use array2 instead of array
then just change the prototype of your function to int *insertionSort
All remaining is to return array2 at the end of task
But be aware of memory leak: https://en.wikipedia.org/wiki/Memory_leak

How to sort one array and get corresponding second array in C++? [duplicate]

This question already has answers here:
sort one array and other array following?
(3 answers)
Closed 7 years ago.
I have two arrays in same size. And want to sort one of the array normally and then sort the next array elements accordingly.
Let's say we have two arrays
e[] = {4,2,3,7,6,8}
s[] = {2,0,4,3,7,9}
First I want to sort array e normally, Then change the element positions of s array according to the changed element positions of e.
This should be the final result
e[] = {2,3,4,6,7,8}
s[] = {0,4,2,7,3,9}
How should I do this? Should I use a class object with these two as private members and then proceed? If so, how to do that?
Create a single array (or vector) of std::pair objects, where first is from the first array and second from the second. Then just use std::sort with a custom comparator function that uses only second from the pair for comparison. Iterate over the sorted array (or vector) and split up into the original arrays.
Note: If the values in each array are tightly coupled then consider putting them in a structure or class instead of using two (or more) distinct arrays.
What I think is use std::map
Assign array e element as the key
And corresponding array s element as the value.
Then sort the may by key
Go trough the map and get the values one by one
If you do this in a class, you can create an array of indices and sort the indices according to the values in e[]. If not doing this within a class, and for a more general approach, create an array of pointers to e[], then sort the pointers according to e[]. Then reorder e[] and s[] according to the pointers, converting the the sorted pointers to an index by using array_of_pointers[i] - &e[0] (or just array_of_pointers[i]-e). You could write your own sort, or use qsort, std::sort, or std::stable sort to sort the array of pointers, with a compare function that compares using dereferenced pointers (compares the values pointed to). Example C code using qsort and reorder in place logic with O(n) time complexity:
int compare(const void *pp0, const void *pp1)
{
int i0 = **(int **)pp0;
int i1 = **(int **)pp1;
if(i0 > i1)return -1;
if(i0 < i1)return 1;
return 0;
}
int main()
{
int e[...];
int s[...];
int *pe[...];
size_t i, j, k;
int te, ts;
/* ... */
/* create array of pointers to e[] */
for(i = 0; i < sizeof(e)/sizeof(e[0]); i++)
pe[i] = &e[i];
/* sort array of pointers */
qsort(pe, sizeof(e)/sizeof(e[0]), sizeof(pe[0]), compare);
/* reorder e[] and s[] according to the array of pointers */
for(i = 0; i < sizeof(e)/sizeof(e[0]); i++){
if(i != pe[i]-e){
te = e[i];
ts = s[i];
k = i;
while(i != (j = pe[k]-e)){
e[k] = e[j];
s[k] = s[j];
pe[k] = &e[k];
k = j;
}
e[k] = te;
s[k] = ts;
pe[k] = &e[k];
}
}
/* ... */
return 0;
}
If you don't want to use other Data structures and stick with the two different integer arrays..
Following code snippet will help you
int _tmain(int argc, _TCHAR* argv[])
{
int e[] = {4,2,3,7,6,8} ;
int s[] = {2,0,4,3,7,9} ;
int temp ;
int Array_Size = 6 ; // don't use hard coded value here, rather calculate from array size
for(int i = 0 ; i < Array_Size ; i++)
{
for(int j = i+1 ; j < Array_Size ; j++)
{
if(e[i] > e[j])
{
// Swap elements in first array
temp = e[j] ;
e[j] = e[i] ;
e[i] = temp ;
// As you want both arrays in sync
// Swap elements in second array here itself
temp = s[j] ;
s[j] = s[i] ;
s[i] = temp ;
}
}
}
return 0;
}
It is quite simple when we use structure.Your basic task is to sort two arrays. I want to suggest one method regarding it. Use a structure having two variables x and y which are used here for two arrays. Make two array of objects of this structure.
struct Point
{
int x,y;
};
struct Point arr[n];
After providing entries to the array of structure objects, make use of STL function
sort(arr,arr+n,myfun);
where myfun is function to sort according to ur need and it is defined as
bool myfun(struct Point a,struct Point b)
{
if(a.x<b.x)
return true;
else
return false;
}
And here is the complete program in c++
#include <bits/stdc++.h>
using namespace std;
struct Point{
int x,y;
};
bool myfun(struct Point a,struct Point b)
{
if(a.x<b.x)
return true;
else
return false;
}
int main()
{
int n; //n is the number of elements of array
cin>>n;
struct Point arr[n];
//Enter first array
for(int i=0;i<n;i++)
cin>>arr[i].x;
//Enter second array
for(int i=0;i<n;i++)
cin>>arr[i].y;
//sorting with the help of myfun
sort(arr,arr+n,myfun);
//now print the arrays
for(int i=0;i<n;i++)
cout<<arr[i].x<<" ";
cout<<"\n";
for(int i=0;i<n;i++)
cout<<arr[i].y<<" ";
return 0;
}
void bubbleSort(int e[], int s[], int n) {
bool swapped = true;
int j = 0;
int tmp;
while (swapped) {
swapped = false;
j++;
for (int i = 0; i < n - j; i++) {
if (e[i] > e[i + 1]) {
tmp = e[i];
e[i] = e[i + 1];
e[i + 1] = tmp;
tmp = s[i];
s[i] = s[i + 1];
s[i + 1] = tmp;
swapped = true;
}
}
}
}

How can i return an array c++?

I am trying to generate some lotto numbers and return the array that contain these numbers but I cant go any further; Help please
void getLotto(int rad[7]) {
int numbers[7];
for (int i = 0; i < 7; i++) {
numbers[i] = rand() % 35 + 1;
}
for (int j = 0; j < 7; j++) {
int n = rand() % 35 + 1;
if (n == numbers[j]) {
numbers[j] = rand() % 35 + 1;
return;
}
}
}
Arrays can't be returned by functions. A common thing to do is to dynamically allocate the array and return a pointer to its first element. This will work in your case but will generate a requirement for the caller to manage the memory (delete[] the new[]'ed memory). That's why C++ provides us with standard array classes: Use and return a std::vector. If you have C++11 support, return std::array.
Following may help, using Fisher–Yates_shuffle:
// Fisher–Yates_shuffle
// http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
std::vector<int> FisherYatesShuffle(std::size_t size, std::size_t max_size, std::mt19937& gen)
{
assert(size < max_size);
std::vector<int> res(size);
for(std::size_t i = 0; i != max_size; ++i) {
std::uniform_int_distribution<> dis(0, i);
std::size_t j = dis(gen);
if (j < res.size()) {
if (i != j) {
res[i] = res[j];
}
res[j] = 1 + i;
}
}
return res;
}
Live example
std::vector and std::array are better than regular arrays, but if you want to use regular arrays you can modify your function as follows:
// Arguments: renamed the array, added N (# of array elements)
void getLotto(int numbers[], size_t N) {
//int numbers[7]; // commented out local variable
for (int i = 0; i < N; i++) {
numbers[i] = rand() % 35 + 1;
}
for (int j = 0; j < N; j++) {
int n = rand() % 35 + 1;
if (n == numbers[j]) {
numbers[j] = rand() % 35 + 1;
return;
}
}
}
The brackets in int numbers[] indicates that the argument is an array, and what is actually passed is a pointer to the first element of the array. Modifying numbers in getLotto() modifies the array passed to the function.
The second argument is of type size_t because it is the platform-dependent alias for the unsigned integral type used by your system to represent the size of objects (like arrays).
This isn't as safe in that the function has to trust that numbers actually has N elements, but this is how you have a function modify a regular array instead of a container like std::vector.
You would call the function like this:
size_t N;
int numbers[N];
getLotto(numbers, N);
C++ does not allow to return an entire array as an argument to a function. However, you can return a pointer to an array by specifying the array's name without an index.
If you want to return a single-dimension array from a function, you would have to declare a function returning a pointer as in the following example:
int * myFunction()
{
.
.
.
}
Second point to remember is that C++ does not advocate to return the address of a local variable to outside of the function so you would have to define the local variable as static variable.
Now, consider the following function, which will generate 10 random numbers and return them using an array and call this function as follows:
#include <iostream>
#include <ctime>
using namespace std;
// function to generate and retrun random numbers.
int * getRandom( )
{
static int r[10];
// set the seed
srand( (unsigned)time( NULL ) );
for (int i = 0; i < 10; ++i)
{
r[i] = rand();
cout << r[i] << endl;
}
return r;
}
// main function to call above defined function.
int main ()
{
// a pointer to an int.
int *p;
p = getRandom();
for ( int i = 0; i < 10; i++ )
{
cout << "*(p + " << i << ") : ";
cout << *(p + i) << endl;
}
return 0;
}
When the above code is compiled together and executed, it produces result something as follows
624723190
1468735695
807113585
976495677
613357504
1377296355
1530315259
1778906708
1820354158
667126415
*(p + 0) : 624723190
*(p + 1) : 1468735695
*(p + 2) : 807113585
*(p + 3) : 976495677
*(p + 4) : 613357504
*(p + 5) : 1377296355
*(p + 6) : 1530315259
*(p + 7) : 1778906708
*(p + 8) : 1820354158
*(p + 9) : 667126415
There are two main ways of accomplishing this.
note: I'm not sure what your second for loop is doing. I guess the intention was to ensure that the numbers are all unique? You might want to take a look at it as that is not what it is doing.
For the purposes of this question, I've cut it down to just generating the random numbers to populate the array.
The first is to take your code and fix it to put the generated numbers into the array that was passed in:
#include <iostream>
void getLotto(int numbers[7]) {
for (int i = 0; i < 7; i++)
{numbers[i] = rand() % 35 + 1;}
return;
}
int main()
{
srand(time(0));
int lotto_numbers[7];
getLotto(lotto_numbers);
for (int i = 0; i < 7; i++)
{std::cout<<lotto_numbers[i]<<std::endl;}
}
numbers isn't actually passed in as an int[] but instead as an int* pointing to the array. This means that any changes you make to it in the function are changed in the original data.
Bear in mind that you need to keep track of your array bounds though, as the array could be defined as
int lotto_numbers[6]
which means that
numbers[7]
would be out of bounds.
The second method is to create the array on the heap. This means that you don't need to pass in an array but you can instantiate it in the function
I'm not actually going to provide the code for this here. Mainly because for something simple like this, the memory management is more trouble than it is worth. (you need to remember to call delete[] for everything created on the heap etc).
Instead, lets use something with memory management built in:
#include <iostream>
#include <vector>
std::vector<int> getLotto() {
std::vector<int> numbers;
numbers.reserve(7);
for (int i = 0; i < 7; i++) {
//numbers[i] = rand() % 35 + 1;
//would work, but is unsafe as you could potentially reference somthing out of range
//this is safer:
numbers.push_back(rand() % 35 + 1);
}
return numbers;
}
int main()
{
srand(time(0));
std::vector<int> lotto_numbers = getLotto();
for (auto i = lotto_numbers.begin(); i != lotto_numbers.end(); i++)
{
std::cout<<*i<<std::endl;
}
}
The vector handles the memory management for you. The vector can be returned, and the returned vector will still point at the allocated memory on the heap we have just populated. We don't need to free it as this will be done automatically when the vector goes out of scope.

Inserting an element into an array

How can I make an inset method that will add a number into the array in the correct order?
void addElement(int table[], int element, int length) {
int x = 0;
int temporary=0;
cout<<length<<endl;
if(length == 1) {
table[0] = element;
}
else {
if(length == 2) {
if (table[0] > element) {
int temp = table[0];
table[0] = element;
table[1] = temp;
}
else {
table[1] = element;
}
}
else {
for(int i = 0; i< length && x == 0; i++) {
if(element<table[i] && element>=table[i-1]) {
for(int y = i; y<length; y++) {
temporary = table[y+2];
int temp = table[y];
table[y] = element;
table[y+1] = table
}
}
}
}
}
}
This is as far as I have gotten. In my main class I have worked it out so that array is increased by 1. So there is one open space at the end of the array for everything to be pushed back by 1.
You can scan the array from back to front, moving values up until you find the correct insertion point.
void addElement(int *table, int element, int length)
{
int i = length - 1;
for (; i > 0 && table[i-1] > element; --i)
{
table[i] = table[i-1];
}
table[i] = element;
}
Write a shiftElements function, write a findIndexOfFirstGreaterThan function, then in addElement - find the index, if -1 then put in last slot, else shift elements using index, then a[index]=elem;
Draw yourself an example, then work out a list of very simple steps required to do what you want.
Then write code that does those steps.
Im not sure if this is what your looking for, but I think you want something that adds an element depending on its integer value. Also, I do not have access to a compiler at this moment so there might be a couple of errors. The code below is just written to give you a brief idea of what you could do, but probably not a perfect solution to your problem.
int addElement (int element, int array [], int length)
{
vector <int> vectorOfInts; //vector to store current order of ints
vector <int> vectorOfArrangedInts; //vector to store arranged order
for (int counter = 0; counter < length; counter ++) //loop to fill the array with values
{
vectorOfInts.push_back (array [counter]);
}
for (int counter = 0; counter < vectorOfInts.length(); counter ++) //loop through all elements
{
int temp = 0; //stores temp value of biggest number found at a specific moment
int elementIndex; //stores indexes
for (int counterTwo = 0; counterTwo < vectorOfInts.length(); counterTwo ++) //loop through all elements to find the biggest array
{
if (vectorOfInts.at (counterTwo) >= temp) //if value is bigger than current biggest number
{
temp = vectorOfInts.at (counterTwo); //change temp value
elementIndex = counterTwo; //remember index
}
}
vectorOfArrangedInts.push_back (vectorOfInts.at(elementIndex)); //add the biggest number to the arranged values
vectorOfInts.erase (vectorOfInts.begin() + elementIndex); //remove the biggest element
}