Deleting elemnt from array and calculating sum - c++

Number can't be in array if it can be divided by number of elements of array (for example: in array which has 10 elements, numbers 1,2,5 and 10 are not "welcome"). So I need to find all these elements in array and kick them out. After that length of array changes, and then some other elements can be "not welcome" in array. I have to repeat it until array is without these elements. In the end, I have to calculate remaining elements and print them out. (I'm using C++)
I didn't know how to delete element from array, and just set value to 0.
I get input n (number of elements in array) and then all of these elements.
So, I already tried it but I'm sure there is much more effective way to do it :P Here is the code:
int main()
{
short int b = 0;
short int n;
int result = 0;
cin >> n;
int m = n;
int numbers[n];
for (int i = 0; i < n; i++) {
cin >> numbers[i];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j<=n; j++) {
if(numbers[j] != 0) {
if(n % numbers[j] == 0) {
numbers[j] = 0;
b = b + 1;
} }
}
n = n - b;
b = 0;
}
for (int i = 0; i < m; i++) {
result += numbers[i];
}
cout << result;
return 0;
}
example input: 10 1 2 3 4 5 6 7 8 9 10
example output: 24

I didn't know how to delete element from array
It is not possible to "delete element from array". An array of n elements begins its life with n elements, has n elements throughout its entire lifetime, and ends its life with n elements. It is not possible to change the size of an array.
Another problem:
cin >> n;
int numbers[n];
The size of an array must be a compile time constant. n is not a compile time constant. This is not a well-formed C++ program.
An array of runtime size must be allocated dynamically. The easiest solution is to use std::vector. The size of a vector can change, and you can use std::vector::erase to remove elements from it.

Related

Segmentation fault on large size array with heap allocation

The following code gives me a segmentation fault when run on a 4Gb machine even after i dynamically allocate the space to the array holding 10 million entries. It works fine with 1 million entries i.e. n = 1000000. The following code sorts integer values along with their index value using radix sort. What should i do to make this program work for 10 million entries.?
int main()
{
int n=10000000; // 10 million entries
int *arr=new int [n]; // declare heap memory for array
int *arri=new int [n]; // declare heap memory for array index
for(int i=0;i<n;i++) // initialize array with random number from 0-100
{
arr[i]=((rand()%100)+0);
}
for(i=0;i<n;i++) // initialize index position for array
{
arri[i]=i;
}
radixsort(arr, n ,arri);
return 0;
}
// The main function to that sorts arr[] of size n using Radix Sort
void radixsort(int *arr, int n,int *arri)
{ int m=99; //getMax(arr,n,arri);
// Find the maximum number to know number of digits
// Do counting sort for every digit. Note that instead
// of passing digit number, exp is passed. exp is 10^i
// where i is current digit number
for (int exp = 1; m/exp > 0; exp *= 10)
countSort(arr, n, exp,arri);
}
void countSort(int *arr, int n, int exp,int *arri)
{
int output[n],output1[n]; // output array
int i, count[10] = {0};
// Store count of occurrences in count[]
for (i = 0; i < n; i++)
{
count[ (arr[i]/exp)%10 ]++;
}
// Change count[i] so that count[i] now contains actual
// position of this digit in output[]
for (i = 1; i < 10; i++)
count[i] += count[i - 1];
// Build the output array
for (i = n - 1; i >= 0; i--)
{
output[count[ (arr[i]/exp)%10 ] - 1] = arr[i];
output1[count[ (arr[i]/exp)%10 ] - 1] = arri[i];
count[ (arr[i]/exp)%10 ]--;
}
// Copy the output array to arr[], so that arr[] now
// contains sorted numbers according to current digit
for (i = 0; i < n; i++)
{
arr[i] = output[i];
arri[i]=output1[i];
}
}
The problem is in countSort. The output and output1 arrays are local arrays, not dynamically allocated, and they're too big for local variables. You're also using the C feature of variable-length arrays, which aren't part of standard C++. Change them to:
int *output = new int[n];
int *output1 = new int[n];
and add
delete[] output;
delete[] output1;
at the end of the function.

Function behaves badly when passing dynamically allocated pointer

I have this function
void shuffle_array(int* array, const int size){
/* given an array of size size, this is going to randomly
* attribute a number from 0 to size-1 to each of the
* array's elements; the numbers don't repeat */
int i, j, r;
bool in_list;
for(i = 0; i < size; i++){
in_list = 0;
r = mt_lrand() % size; // my RNG function
for(j = 0; j < size; j++)
if(array[j] == r){
in_list = 1;
break;
}
if(!in_list)
array[i] = r;
else
i--;
}
}
When I call this function from
int array[FIXED_SIZE];
shuffle_array(array, FIXED_SIZE);
everything goes all right and I can check the shuffling was according to expected, in a reasonable amount of time -- after all, it's not that big of an array (< 1000 elements).
However, when I call the function from
int *array = new int[dynamic_size];
shuffle_array(array, dynamic_size);
[...]
delete array;
the function loops forever for no apparent reason. I have checked it with debugging tools, and I can't say tell where the failure would be (in part due to my algorithm's reliance on random numbers).
The thing is, it doesn't work... I have tried passing the array as int*& array, I have tried using std::vector<int>&, I have tried to use random_shuffle (but the result for the big project didn't please me).
Why does this behavior happen, and what can I do to solve it?
Your issue is that array is uninitialized in your first example. If you are using Visual Studio debug mode, Each entry in array will be set to all 0xCC (for "created"). This is masking your actual problem (see below).
When you use new int[dynamic_size] the array is initialized to zeros. This then causes your actual bug.
Your actual bug is that you are trying to add a new item only when your array doesn't already contain that item and you are looking through the entire array each time, however if your last element of your array is a valid value already (like 0), your loop will never terminate as it always finds 0 in the array and has already used up all of the other numbers.
To fix this, change your algorithm to only look at the values that you have put in to the array (i.e. up to i).
Change
for(j = 0; j < size; j++)
to
for(j = 0; j < i; j++)
I am going to guess that the problem lies with the way the array is initialized and the line:
r = mt_lrand() % size; // my RNG function
If the dynamically allocated array has been initialized to 0 for some reason, your code will always get stack when filling up the last number of the array.
I can think of the following two ways to overcome that:
You make sure that you initialize array with numbers greater than or equal to size.
int *array = new int[dynamic_size];
for ( int i = 0; i < dynnamic_size; ++i )
array[i] = size;
shuffle_array(array, dynamic_size);
You can allows the random numbers to be between 1 and size instead of between 0 and size-1 in the loop. As a second step, you can subtract 1 from each element of the array.
void shuffle_array(int* array, const int size){
int i, j, r;
bool in_list;
for(i = 0; i < size; i++){
in_list = 0;
// Make r to be betwen 1 and size
r = rand() % size + 1;
for(j = 0; j < size; j++)
if(array[j] == r){
in_list = 1;
break;
}
if(!in_list)
{
array[i] = r;
}
else
i--;
}
// Now decrement the elements of array by 1.
for(i = 0; i < size; i++){
--array[i];
// Debugging output
std::cout << "array[" << i << "] = " << array[i] << std::endl;
}
}
You are mixing C code with C++ memory allocation routines of new and delete. Instead stick to pure C and use malloc/free directly.
int *array = malloc(dynamic_size * sizeof(int));
shuffle_array(array, dynamic_size);
[...]
free(array);
On a side note, if you are allocating an array using the new[] operator in C++, use the equivalent delete[] operator to properly free up the memory. Read more here - http://www.cplusplus.com/reference/new/operator%20new[]/

my function always returns a huge number

Now my function works better, but it did't return the minimum number, it returns the second largest... Could anyone help me? I can't find the error.
#include <iostream>
#include <cstdio>
#include <cstdlib>
void add_min(int*& a, int n){
int c;
for(int i = 0; i < n - 1; i++){
if(a[i + 1] < a[i]){
c = a[i + 1];
}
else{
c = a[i];
}
}
std::cout<< c <<std::endl;
for(int s = 0; s < n; s++){
a[s] += c;
}
for(int z = 0;z < n; z++){
std::cout<< a[z] <<std::endl;
}
}
int main(){
int n,i;
std::cout<< "please enter the dimention of the array" <<std::endl;
std::cin>> n;
int *arr = new int[n-1];
std::cout<< "please enter the integers in the array" <<std::endl;
for(i = 0;i < n; i++){
std::cin>>arr[i];
}
add_min(arr, n);
delete [] arr;
return 0;
}
Problem 1 :
int c, a[n];
b = a[n];
size of a = n , therefore you can at maximum access a[n-1] , not a[n] since index starts from 0 , not 1 in c .
Problem 2 :
have you initialized the values of array a ?
when arrays are initialized in functions , they are filled with random values .
Besides the problem mentioned in my comment, the problem is that you're using an uninitialized local array, which means it will contain seemingly random data. You also start out by reading a value out of bounds with b = a[n];
I think what you really meant to do was to pass in the complete array as an argument, instead of creating new in the function.
These huge numbers you are talking about are the definition of undefined output. Why are you getting this?
In your loop, you're doing:
if(a[i + 1] < a[i])
But remember that arrays are zero-based in C++, so you're getting out of bounds in the last iteration, because i + 1 will be n, and the array's size is n-1 (Indexes run in the range [0, n-1]).
Tip: Debugging your code can save your time (and your life), use the debugger!
Furthermore, more important issue, you're using an uninitialized array that initially contains garbage values.

Swap elements in array to reverse an array

I got an assignment to reverse an dynamic array in C++. So far, from my logic, I thinking of loop thru the array to reverse it. And here comes my code :
int main ()
{
const int size = 10;
int num_array[size];
srand (time(NULL));
for (int count = 0; count< sizeof(num_array)/sizeof(num_array[0]) ; count++){
/* generate secret number between 1 and 100: */
num_array[count] = rand() % 100 + 1;
cout << num_array[count] << " " ;
}
reverse(num_array[size],size);
cout << endl;
system("PAUSE");
return 0;
}
void reverse(int num_array[], int size)
{
for (int count =0; count< sizeof(num_array)/sizeof(num_array[0]); count++){
cout << num_array[sizeof(num_array)/sizeof(num_array[0])-1-count] << " " ;
}
return;
}
Somehow I think my logic was there but this code doesn't works, there's some error. However, my teacher told me that this isn't the way what the question wants. And here is the question :
Write a function reverse that reverses the sequence of elements in an array. For example, if reverse is called with an array containing 1 4 9 16 9 7 4 9 11,
then the array is changed to 11 9 4 7 9 16 9 4 1.
So far, she told us in the reverse method, you need to swap for the array element. So here's my question how to swap array element so that the array entered would be reversed?
Thanks in advance.
Updated portion
int main ()
{
const int size = 10;
int num_array[size];
srand (time(NULL));
for (int count = 0; count< size ; count++){
/* generate secret number between 1 and 100: */
num_array[count] = rand() % 100 + 1;
cout << num_array[count] << " " ;
}
reverse(num_array,size);
cout << endl;
system("PAUSE");
return 0;
}
void reverse(int num_array[], const int& size)
{
for (int count =0; count< size/2; count++){
int first = num_array[0];
int last = num_array[count-1];
int temp = first;
first = last;
last = temp;
}
}
You reverse function should look like this:
void reverse(int* array, const size_t size)
{
for (size_t i = 0; i < size / 2; i++)
{
// Do stuff...
}
}
And call it like:
reverse(num_array, size);
I am no C++ programmer, however I do see an easy solution to this problem. By simply using a for loop and an extra array (of the same size) you should be able to reverse the array with ease.
By using a for loop, starting at the last element of the array, and adding them in sequence to the new array, it should be fairly simple to end up with a reversed array. It would be something like this:
Declare two arrays of the same size (10 it seems)
Array1 contains your random numbers
Array2 is empty, but can consist of 10 elements
Also declare an integer, which will keep track of the progression of the for loop, but in the opposite direction. i.e not from the end but from the start.
Counter = 0
Next you will need to create a for loop to start from the end of the first array, and add the values to the start of the second array. Thus we will create a for loop to do so. The for loop will be something like this:
for(int i = lengthOfArray1; i > 0; i--){
Array2[Counter] = Array1[i]
Counter++
}
If you only wish to print it out, you would not need the counter, or the second array, you will simply use the Array1 elements and print them out with that style of for loop.
That's it. You could set Array1 = Array2 afterward if you wished to keep Array1 the original for some reason. Hope this helps a bit, changing it to C++ is your job on this one unfortunately.
You're not actually swapping the elements in the array, you're just printing them out. I assume she wants you to actually change what is stored in the array.
As a hint, go through the array swapping the first and last element, then the 2nd and 2nd last element, etc. You only need to loop for size/2 too. As you have the size variable, just use that instead of all the sizeof stuff you're doing.
I would implement the function like following
void reverse(int A[], int N)
{
for (int i=0, j=N-1; i<j; i++, j--){
int t = A[i];
A[i] = A[j];
A[j] = t;
}
}

Convert one dimensional array to two dimensional array

For my homework it is given one dimensional array and i have to convert it in a two dimensional array. The two dimensional array has 2 for the number of columns, because i have to represent the one dimensional array as pairs(the value of the number, the number of appearences in the array).
This is what have tried. The error appears on the last 2 lines of code: access violation writing location 0xfdfdfdfd.
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
const int NR=17;
int arr[NR]={6,7,3,1,3,2,4,4,7,5,1,1,5,6,6,4,5};
int **newArr;
int count=0;
int countLines=0;
int searched;
for(int i=0;i<NR;i++)
{
newArr=new int*[countLines];
for(int i=0;i<countLines;i++)
{
newArr[i]=new int[2];
}
searched=arr[i];
if(i>0)
{
for(int k=0;k<countLines;k++)
{
if(newArr[countLines][0] == searched)
{
searched=arr[i]++;
}
for(int j=0;j<NR;j++)
{
if(searched==arr[j])
{
count++;
}
}
countLines++;
}
}
else
{
for(int j=0;j<NR;j++)
{
if(searched==arr[j])
{
count++;
}
}
countLines++;
}
newArr[countLines][0]=searched;
newArr[countLines][1]=count;
}
}
First you are using newArr in the first loop before allocating it any memory. You cannot dereference a pointer which owns no legal memory. It results in undefined behavior.
Secondly in the last part, you are allocating newArr a memory equal to countLines thus.
newArr = new int*[countLines] ;
It means that the indices in the first dimension of newArr are 0------>countLines-1. Doing newArr[countLines][0] = searched ; is again undefined. Make it newArr[countLines - 1].
I'm not going to bother with a line-by-line code analysis since (a) you're changing it while people are answering your question and (b) it would literally take too long. But here's a summary (non-exhaustive) of klunkers:
You are leaking memory (newArr) on each loop iteration starting with the second.
You're out-of-bounds on your array access multiple times.
You should not need to use a pointer array at all to solve this. A single array of dimension [N][2] where N is the number of unique values.
One (of countless many) way you can solve this problem is presented below:
#include <iostream>
#include <algorithm>
int main()
{
// 0. Declare array and length
int arr[]={6,7,3,1,3,2,4,4,7,5,1,1,5,6,6,4,5};
const size_t NR = sizeof(arr)/sizeof(arr[0]);
// 1. sort the input array
std::sort(arr, arr+NR);
/* alternaive sort. for this input size bubble-sort is
more than adequate, in case your limited to not being
allowed to use the standard library sort */
/*
for (size_t i=0;i<NR;++i)
for (size_t j=i+1;j<NR;++j)
if (arr[i] > arr[j])
{
arr[i] ^= arr[j];
arr[j] ^= arr[i];
arr[i] ^= arr[j];
}
*/
// 2. single scan to determine distinct values
size_t unique = 1;
for (size_t i=1;i<NR;++i)
if (arr[i] != arr[i-1])
unique++;
// 3. Allocate a [unique][2] array
int (*newArr)[2] = new int[unique][2];
// 4. Walk array once more, accumulating counts
size_t j=0;
newArr[j][0] = arr[0];
newArr[j][1] = 1;
for (size_t i=1;i<NR;++i)
{
if (arr[i] != arr[i-1])
{
newArr[++j][0] = arr[i];
newArr[j][1] = 0;
}
++newArr[j][1];
}
// 5. Dump output
for (size_t i=0;i<unique;++i)
cout << newArr[i][0] << " : " << newArr[i][1] << endl;
delete [] newArr;
return EXIT_SUCCESS;
}
Output
1 : 3
2 : 1
3 : 2
4 : 3
5 : 3
6 : 3
7 : 2