Get the smallest difference of all possible element combinations in an array - c

I have a very, very long array and I have to get the minimum difference of all possible combinations of 2 elements.
This is my code:
[...]
int diff = 1000000; // a very big difference that i'm sure is too big
int tmpDiff; // swap
//Compare
for (size_t i = 0; i < N; i++) { // I try every combination of 2 elements of array
for (size_t j = i + 1; j < N; j++) { // don't repeat same elements
tmpDiff = abs(array[i] - array[j]); // get the difference
if (diff > tmpDiff) { // if it is smaller is the difference i need
diff = tmpDiff;
}
}
}
[...]
It takes too much time. How could we optimize performances?

Sort the array first. Then you only need to compare consecutive values. And you don't even need to use abs() as you know which of the two elements it the bigger one.
If the array must not be changed, copy it first (not shown below).
#include <limits.h>
#include <stdlib.h>
// compare function for integer, compatible with qsort
int int_cmp(const void *a, const void *b)
{
const int *ia = (const int *)a; // casting pointer types
const int *ib = (const int *)b;
return *ia - *ib;
}
...
int diff = INT_MAX;
int d;
// sort
qsort(array, N, sizeof(array[0]), int_cmp);
// compare consecutive elements
for (size_t i = 1; i < N; i++) {
d = array[i] - array[i - 1];
if (d < diff)
diff = d;
}
Update
qsort sorts an array using the Quicksort algorithm. The cost of the sorting is of the order O(n ln n) as opposed to O(n^2) if you have two nested for loops. For bigger arrays (n > 100), this can make a huge difference. Just do the math: approx. 500 vs. 10,000.
The comparison function passed to qsort is always tricky as qsort is written such that it works with arrays of any type. The function is passed the address of (pointer to) two elements in the array. For small types such as integer, it would be handy if it passed the integers directly. But instead, you have to deal with the address. So what you do is two things:
Convert the pointer to a more specific type, i.e. from a pointer of any type (void*) to a pointer to an integer (int*).
Dereference the pointer, i.e. get the effective value by using the * operator, in this case *ia and *ib.
The functions needs to return a number less than 0 if the first integer is smaller than the second one, 0 if they are equal and a number greater than 0 if the second number is bigger. So an old trick comes in handy: just return the difference between the first and second number.

Related

why do I have a runtime #2 failure in C when I have enough space and there isn't many data in the array

I'm writing this code in C for some offline games but when I run this code, it says "runtime failure #2" and "stack around the variable has corrupted". I searched the internet and saw some answers but I think there's nothing wrong with this.
#include <stdio.h>
int main(void) {
int a[16];
int player = 32;
for (int i = 0; i < sizeof(a); i++) {
if (player+1 == i) {
a[i] = 254;
}
else {
a[i] = 32;
}
}
printf("%d", a[15]);
return 0;
}
Your loop runs from 0 to sizeof(a), and sizeof(a) is the size in bytes of your array.
Each int is (typically) 4-bytes, and the total size of the array is 64-bytes. So variable i goes from 0 to 63.
But the valid indices of the array are only 0-15, because the array was declared [16].
The standard way to iterate over an array like this is:
#define count_of_array(x) (sizeof(x) / sizeof(*x))
for (int i = 0; i < count_of_array(a); i++) { ... }
The count_of_array macro calculates the number of elements in the array by taking the total size of the array, and dividing by the size of one element.
In your example, it would be (64 / 4) == 16.
sizeof(a) is not the size of a, but rather how many bytes a consumes.
a has 16 ints. The size of int depends on the implementation. A lot of C implementations make int has 4 bytes, but some implementations make int has 2 bytes. So sizeof(a) == 64 or sizeof(a) == 32. Either way, that's not what you want.
You define int a[16];, so the size of a is 16.
So, change your for loop into:
for (int i = 0; i < 16; i++)
You're indexing too far off the size of the array, trying to touch parts of memory that doesn't belong to your program. sizeof(a) returns 64 (depending on C implementation, actually), which is the total amount of bytes your int array is taking up.
There are good reasons for trying not to statically declare the number of iterations in a loop when iterating over an array.
For example, you might realloc memory (if you've declared the array using malloc) in order to grow or shrink the array, thus making it harder to keep track of the size of the array at any given point. Or maybe the size of the array depends on user input. Or something else altogether.
There's no good reason to avoid saying for (int i = 0; i < 16; i++) in this particular case, though. What I would do is declare const int foo = 16; and then use foo instead of any number, both in the array declaration and the for loop, so that if you ever need to change it, you only need to change it in one place. Else, if you really want to use sizeof() (maybe because one of the reasons above) you should divide the return value of sizeof(array) by the return value of sizeof(type of array). For example:
#include <stdio.h>
const int ARRAY_SIZE = 30;
int main(void)
{
int a[ARRAY_SIZE];
for(int i = 0; i < sizeof(a) / sizeof(int); i++)
a[i] = 100;
// I'd use for(int i = 0; i < ARRAY_SIZE; i++) though
}

Adding an element to an array in C without a loop

This is my first time asking so please be gentle lol.
So I am trying to better understand arrays in C. Is there a way I can add an element to an array without using a for loop? The problem is I want to add a new element to the end of the array, but without knowing the size of the array.
So I already have this:
#include <stdlib.h> //not sure if needed but put it just in case
int main(void):
float real[20];
real[]={1,2,3,4,5};
I want to add the number 6 to the array, but I don't want to use real[5]=6. Is there another way to add an element to the end of the array without a loop checking if each element in the array until the element is null? Thanks for your help in advance!
C arrays don't know about their length. If you need arrays that can grow and shrink, you have to keep extra information on how long your active array is. An array that is created on the stack like so:
real array[20] = {1, 2, 3};
will contain twenty elements, the first three initialised with concrete values, the rest initialised to zero. If you want to consider this array as an array of initially three values that can hold up to 20 values, you have to keep the actual array length as an extra variable:
real array[20] = {1, 2, 3};
int narray = 3;
You can then append a value. Take care not to overflow that maximum storage of 20 elements:
if (narray < 20) array[narray++] = 9;
You can read the last value and remove it from the array:
if (narray) printf("%g\n", array[--narry]);
Here, you have to take care not to underflow the array. (Also, don't decrement narray more than once in the same expression, which will lead to undefined behaviour.)
If you write a function that operates on the array, pass both array and length:
void array_print(float array[], int n)
{
int i;
for (i = 0; i < n; i++) {
if (i) printf(", ");
printf("%g", array[i]);
}
printf("\n");
}
and call it like so:
array_print(array, narray);
Another approach is to keep a sentinel value like 0.0. This can be useful in some cases, but it has the disadvantage that you have to traverse the whole array to find out the length. It also removes the sentinel from the range of valid values that your array can hold.
The advantage here is, of course, that the array is "self-contained", i.e. you don't have to pass array and length to a function; just the array is enough. When appending you still have to take care not to overflow the maximum storage, which makes this approach cumbersome.
The only way is to keep a pointer to the next free position in the array. For example
#include <stdio.h>
float * copy( const float *src, size_t n, float *dst )
{
while ( n-- ) *dst++ = *src++;
return dst;
}
int main(void)
{
float real[20];
float *p = real;
p = copy( ( float [] ){ 1, 2, 3, 4, 5 }, 5, p );
p = copy( ( float [] ){ 6, 7 }, 2, p );
for ( float *q = real; q != p; ++q ) printf( "%1.1f ", *q );
printf( "\n" );
return 0;
}
The output is
1.0 2.0 3.0 4.0 5.0 6.0 7.0
You always can check whether p points within the array using condition
p < real + 20
The other approach is to use a structure that contains an array. For example
struct Array
{
enum { N = 20 };
float real[N];
size_t n; /* current number of filled elements */
};
With a little help of the preprocessor, you can use a compound literal to get the size:
int main(void)
{
#define REAL_VALUES 1, 2, 3, 4, 5
float real[20] = {REAL_VALUES};
real[sizeof((float[]){REAL_VALUES}) / sizeof(float)] = 6;
return 0;
}
In C you can get the length of an array with the expression sizeof (array) / sizeof (array)[0], or even better, by defining a macro:
#define LEN(array) \
((int) (sizeof (array) / sizeof (array)[0]))
What you describe is not adding an element to the end of the array but rather adding an element after the last element inserted. For that you need a variable that keeps track of the element count:
int count = 0;
float x;
...
if (count < LEN(real)) {
real[count] = x;
count++;
}
Observe, however, that once you have passed the array to a function its length is gone, so you need to pass the array length to the function as well:
void foo(float a[], int len);
...
foo(real, LEN(real));
You can use memset() to make space for your element in your array and then insert your element at specific position.
Here is sample code below.
/*Make space for number to insert.*/
memmove(&arr[pos+1],&arr[pos],(ARR_SIZE+1-pos)*sizeof(int));
arr[pos] = num;/*insert the number.*/
Full code snipet could be found here InsertElement

Array percentage algorithm implementation

So I just stared programming in C a few days ago and I have this program which takes an unsorted file full of integers, sorts it using quicksort
1st algorithm
Any suggestions on what I have done wrong in this?
From what you have described, it sounds like you are almost there. You are attempting to get the first element of a collection that has a value equal to (or just greather than) 90% of all the other members of the collection. You have already done the sort. The rest should be simply following these steps (if I have understood your question):
1) sort collection into an into array (you've already done this I think)
2) count numbers in collection, store in float n; //number of elements in collection
3) index through sorted array to the 0.9*n th element, (pick first one beyond that point not a duplicate of previous)
4) display results
Here is an implementation (sort of, I did not store n) of what I have described: (ignore the random number generator, et al., it is just a fast way to get an array)
#include <ansi_c.h>
#include <windows.h>
int randomGenerator(int min, int max);
int NotUsedRecently (int number);
int cmpfunc (const void * a, const void * b);
int main(void)
{
int array[1000];
int i;
for(i=0;i<1000;i++)
{
array[i]=randomGenerator(1, 1000);
Sleep(1);
}
//sort array
qsort(array, 1000, sizeof(int), cmpfunc);
//pick the first non repeat 90th percent and print
for(i=900;i<999;i++)
{
if(array[i+1] != array[i])
{
printf("this is the first number meeting criteria: %d", array[i+1]);
break;
}
}
getchar();
return 0;
}
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int randomGenerator(int min, int max)
{
int random=0, trying=0;
trying = 1;
srand(clock());
while(trying)
{
random = (rand()/32767.0)*(max+1);
(random >= min) ? (trying = 0) : (trying = 1);
}
return random;
}
And here is the output for my first randomly generated array (centering around the 90th percentile), compared against what the algorithm selected: Column on left is the element number, on the right is the sorted list of randomly generated integers. (notice it skips the repeats to ensure smallest value past 90%)
In summary: As I said, I think you are already, almost there. Notice how similar this section of my code is to yours:
You have something already, very similar. Just modify it to start looking at 90% index of the array (whatever that is), then just pick the first value that is not equal to the previous.
One issue in your code is that you need a break case for your second algorithm, once you find the output. Also, you cannot declare variables in your for loop, except under certain conditions. I'm not sure how you got it to compile.
According this part:
int output = array[(int)(floor(0.9*count)) + 1];
int x = (floor(0.9*count) + 1);
while (array[x] == array[x + 1])
{
x = x + 1;
}
printf(" %d ", output);
In while you do not check if x has exceeded count... (What if all the top 10% numbers are equal?)
You set output in first line and print it in last, but do not do antything with it in meantime. (So all those lines in between do nothing).
You definitely are on the right track.

Estimating memory scope of erlang datastructure

Being a former C programmer and current Erlang hacker one question has popped up.
How do I estimate the memory scope of my erlang datastructures?
Lets say I had an array of 1k integers in C, estimating the memory demand of this is easy, just the size of my array, times the size of an integer, 1k 32bit integers would take up 4kb or memory, and some constant amount of pointers and indexes.
In erlang however estimating the memory usage is somewhat more complicated, how much memory does an entry in erlangs array structure take up?, how do I estimate the size of a dynamically sized integer.
I have noticed that scanning over integers in array is fairly slow in erlang, scanning an array of about 1M integers takes almost a second in erlang, whereas a simple piece of c code will do it in arround 2 ms, this most likely is due to the amount of memory taken up by the datastructure.
I'm asking this, not because I'm a speed freak, but because estimating memory has, at least in my experience, been a good way of determining scalability of software.
My test code:
first the C code:
#include <cstdio>
#include <cstdlib>
#include <time.h>
#include <queue>
#include <iostream>
class DynamicArray{
protected:
int* array;
unsigned int size;
unsigned int max_size;
public:
DynamicArray() {
array = new int[1];
size = 0;
max_size = 1;
}
~DynamicArray() {
delete[] array;
}
void insert(int value) {
if (size == max_size) {
int* old_array = array;
array = new int[size * 2];
memcpy ( array, old_array, sizeof(int)*size );
for(int i = 0; i != size; i++)
array[i] = old_array[i];
max_size *= 2;
delete[] old_array;
}
array[size] = value;
size ++;
}
inline int read(unsigned idx) const {
return array[idx];
}
void print_array() {
for(int i = 0; i != size; i++)
printf("%d ", array[i]);
printf("\n ");
}
int size_of() const {
return max_size * sizeof(int);
}
};
void test_array(int test) {
printf(" %d ", test);
clock_t t1,t2;
t1=clock();
DynamicArray arr;
for(int i = 0; i != test; i++) {
//arr.print_array();
arr.insert(i);
}
int val = 0;
for(int i = 0; i != test; i++)
val += arr.read(i);
printf(" size %g MB ", (arr.size_of()/(1024*1024.0)));
t2=clock();
float diff ((float)t2-(float)t1);
std::cout<<diff/1000<< " ms" ;
printf(" %d \n", val == ((1 + test)*test)/2);
}
int main(int argc, char** argv) {
int size = atoi(argv[1]);
printf(" -- STARTING --\n");
test_array(size);
return 0;
}
and the erlang code:
-module(test).
-export([go/1]).
construct_list(Arr, Idx, Idx) ->
Arr;
construct_list(Arr, Idx, Max) ->
construct_list(array:set(Idx, Idx, Arr), Idx + 1, Max).
sum_list(_Arr, Idx, Idx, Sum) ->
Sum;
sum_list(Arr, Idx, Max, Sum) ->
sum_list(Arr, Idx + 1, Max, array:get(Idx, Arr) + Sum ).
go(Size) ->
A0 = array:new(Size),
A1 = construct_list(A0, 0, Size),
sum_list(A1, 0, Size, 0).
Timing the c code:
bash-3.2$ g++ -O3 test.cc -o test
bash-3.2$ ./test 1000000
-- STARTING --
1000000 size 4 MB 5.511 ms 0
and the erlang code:
1> f(Time), {Time, _} =timer:tc(test, go, [1000000]), Time/1000.0.
2189.418
First, an Erlang variable is always just a single word (32 or 64 bits depending on your machine). 2 or more bits of the word are used as a type tag. The remainder can hold an "immediate" value, such as a "fixnum" integer, an atom, an empty list ([]), or a Pid; or it can hold a pointer to data stored on the heap (tuple, list, "bignum" integer, float, etc.). A tuple has a header word specifying its type and length, followed by one word per element. A list cell on the uses only 2 words (its pointer already encodes the type): the head and tail elements.
For example: if A={foo,1,[]}, then A is a word pointing to a word on the heap saying "I'm a 3-tuple" followed by 3 words containing the atom foo, the fixnum 1, and the empty list, respectively. If A=[1,2], then A is a word saying "I'm a list cell pointer" pointing to the head word (containing the fixnum 1) of the first cell; and the following tail word of the cell is yet another list cell pointer, pointing to a head word containing the 2 and followed by a tail word containing the empty list. A float is represented by a header word and 8 bytes of double precision floating-point data. A bignum or a binary is a header word plus as many words as needed to hold the data. And so on. See e.g. http://stenmans.org/happi_blog/?p=176 for some more info.
To estimate size, you need to know how your data is structured in terms of tuples and lists, and you need to know the size of your integers (if too large, they will use a bignum instead of a fixnum; the limit is 28 bits incl. sign on a 32-bit machine, and 60 bits on a 64-bit machine).
Edit: https://github.com/happi/theBeamBook is a newer good resource on the internals of the BEAM Erlang virtual machine.
Is this what you want?
1> erts_debug:size([1,2]).
4
with it you can at least figure out how big a term is. The size returned is in words.
Erlang has integers as "arrays", so you cannot really estimate it in the same way as c, you can only predict how long your integers will be and calculate average amount of bytes needed to store them
check: http://www.erlang.org/doc/efficiency_guide/advanced.html and you can use erlang:memory() function to determine actual amount

Allocate contiguous memory

I'm trying to allocate a large space of contiguous memory in C and print this out to the user. My strategy for doing this is to create two pointers (one a pointer to double, one a pointer to pointer to double), malloc one of them to the entire size (m * n) in this case the pointer to pointer to double. Then malloc the second one to the size of m. The last step will be to iterate through the size of m and perform pointer arithmetic that would ensure the addresses of the doubles in the large array will be stored in contiguous memory. Here is my code. But when I print out the address it doesn't seem to be in contiguous (or in any sort of order). How do i print out the memory addresses of the doubles (all of them are of value 0.0) correctly?
/* correct solution, with correct formatting */
/*The total number of bytes allocated was: 4
0x7fd5e1c038c0 - 1
0x7fd5e1c038c8 - 2
0x7fd5e1c038d0 - 3
0x7fd5e1c038d8 - 4*/
double **dmatrix(size_t m, size_t n);
int main(int argc, char const *argv[])
{
int m,n,i;
double ** f;
m = n = 2;
i = 0;
f = dmatrix(sizeof(m), sizeof(n));
printf("%s %d\n", "The total number of bytes allocated was: ", m * n);
for (i=0;i<n*m;++i) {
printf("%p - %d\n ", &f[i], i + 1);
}
return 0;
}
double **dmatrix(size_t m, size_t n) {
double ** ptr1 = (double **)malloc(sizeof(double *) * m * n);
double * ptr2 = (double *)malloc(sizeof(double) * m);
int i;
for (i = 0; i < n; i++){
ptr1[i] = ptr2+m*i;
}
return ptr1;
}
Remember that memory is just memory. Sounds trite, but so many people seem to think of memory allocation and memory management in C as being some magic-voodoo. It isn't. At the end of the day you allocate whatever memory you need, and free it when you're done.
So start with the most basic question: If you had a need for 'n' double values, how would you allocate them?
double *d1d = calloc(n, sizeof(double));
// ... use d1d like an array (d1d[0] = 100.00, etc. ...
free(d1d);
Simple enough. Next question, in two parts, where the first part has nothing to do with memory allocation (yet):
How many double values are in a 2D array that is m*n in size?
How can we allocate enough memory to hold them all.
Answers:
There are m*n doubles in a m*n 2D-matrix of doubles
Allocate enough memory to hold (m*n) doubles.
Seems simple enough:
size_t m=10;
size_t n=20;
double *d2d = calloc(m*n, sizeof(double));
But how do we access the actual elements? A little math is in order. Knowing m and n, you can simple do this
size_t i = 3; // value you want in the major index (0..(m-1)).
size_t j = 4; // value you want in the minor index (0..(n-1)).
d2d[i*n+j] = 100.0;
Is there a simpler way to do this? In standard C, yes; in C++ no. Standard C supports a very handy capability that generates the proper code to declare dynamically-sized indexible arrays:
size_t m=10;
size_t n=20;
double (*d2d)[n] = calloc(m, sizeof(*d2d));
Can't stress this enough: Standard C supports this, C++ does NOT. If you're using C++ you may want to write an object class to do this all for you anyway, so it won't be mentioned beyond that.
So what does the above actual do ? Well first, it should be obvious we are still allocating the same amount of memory we were allocating before. That is, m*n elements, each sizeof(double) large. But you're probably asking yourself,"What is with that variable declaration?" That needs a little explaining.
There is a clear and present difference between this:
double *ptrs[n]; // declares an array of `n` pointers to doubles.
and this:
double (*ptr)[n]; // declares a pointer to an array of `n` doubles.
The compiler is now aware of how wide each row is (n doubles in each row), so we can now reference elements in the array using two indexes:
size_t m=10;
size_t n=20;
double (*d2d)[n] = calloc(m, sizeof(*d2d));
d2d[2][5] = 100.0; // does the 2*n+5 math for you.
free(d2d);
Can we extend this to 3D? Of course, the math starts looking a little weird, but it is still just offset calculations into a big'ol'block'o'ram. First the "do-your-own-math" way, indexing with [i,j,k]:
size_t l=10;
size_t m=20;
size_t n=30;
double *d3d = calloc(l*m*n, sizeof(double));
size_t i=3;
size_t j=4;
size_t k=5;
d3d[i*m*n + j*m + k] = 100.0;
free(d3d);
You need to stare at the math in that for a minute to really gel on how it computes where the double value in that big block of ram actually is. Using the above dimensions and desired indexes, the "raw" index is:
i*m*n = 3*20*30 = 1800
j*m = 4*20 = 80
k = 5 = 5
======================
i*m*n+j*m+k = 1885
So we're hitting the 1885'th element in that big linear block. Lets do another. what about [0,1,2]?
i*m*n = 0*20*30 = 0
j*m = 1*20 = 20
k = 2 = 2
======================
i*m*n+j*m+k = 22
I.e. the 22nd element in the linear array.
It should be obvious by now that so long as you stay within the self-prescribed bounds of your array, i:[0..(l-1)], j:[0..(m-1)], and k:[0..(n-1)] any valid index trio will locate a unique value in the linear array that no other valid trio will also locate.
Finally, we use the same array pointer declaration like we did before with a 2D array, but extend it to 3D:
size_t l=10;
size_t m=20;
size_t n=30;
double (*d3d)[m][n] = calloc(l, sizeof(*d3d));
d3d[3][4][5] = 100.0;
free(d3d);
Again, all this really does is the same math we were doing before by hand, but letting the compiler do it for us.
I realize is may be a bit much to wrap your head around, but it is important. If it is paramount you have contiguous memory matrices (like feeding a matrix to a graphics rendering library like OpenGL, etc), you can do it relatively painlessly using the above techniques.
Finally, you might wonder why would anyone do the whole pointer arrays to pointer arrays to pointer arrays to values thing in the first place if you can do it like this? A lot of reasons. Suppose you're replacing rows. swapping a pointer is easy; copying an entire row? expensive. Supposed you're replacing an entire table-dimension (m*n) in your 3D array (l*n*m), even more-so, swapping a pointer: easy; copying an entire m*n table? expensive. And the not-so-obvious answer. What if the rows widths need to be independent from row to row (i.e. row0 can be 5 elements, row1 can be 6 elements). A fixed l*m*n allocation simply doesn't work then.
Best of luck.
Never mind, I figured it out.
/* The total number of bytes allocated was: 8
0x7fb35ac038c0 - 1
0x7fb35ac038c8 - 2
0x7fb35ac038d0 - 3
0x7fb35ac038d8 - 4
0x7fb35ac038e0 - 5
0x7fb35ac038e8 - 6
0x7fb35ac038f0 - 7
0x7fb35ac038f8 - 8 */
double ***d3darr(size_t l, size_t m, size_t n);
int main(int argc, char const *argv[])
{
int m,n,l,i;
double *** f;
m = n = l = 10; i = 0;
f = d3darr(sizeof(l), sizeof(m), sizeof(n));
printf("%s %d\n", "The total number of bytes allocated was: ", m * n * l);
for (i=0;i<n*m*l;++i) {
printf("%p - %d\n ", &f[i], i + 1);
}
return 0;
}
double ***d3darr(size_t l, size_t m, size_t n){
double *** ptr1 = (double ***)malloc(sizeof(double **) * m * n * l);
double ** ptr2 = (double **)malloc(sizeof(double *) * m * n);
double * ptr3 = (double *)malloc(sizeof(double) * m);
int i, j;
for (i = 0; i < l; ++i) {
ptr1[i] = ptr2+m*n*i;
for (j = 0; j < l; ++j){
ptr2[i] = ptr3+j*n;
}
}
return ptr1;
}

Resources