It should be simple,two arrays,one with 5 other with 6 elements.
#include <stdlib.h>
#include <stdio.h>
int main()
{
int i=0;
int k=0;
int v[5] = {2,3,4,5,6};
int g[6];
for( i = 1; i <= 6; i++ ){
k= i + 1;
if ( 1 == i && 2 == i)
{
g[k]=v[i];
}
else
{
g[k]=(v[i]+10);
}
printf("%d\n",g[k]);
}
return 0;
}
I got this
13
14
15
16
32776
10
I really wanted
2 3 13 14 15 16
Where is my mistake?Should I create function or what?
Problem 1
Array indexes are 0-based, meaning v[0] and g[0] are the first element of the arrays. All your i and k are off by one 1.
Problem 2
1 == i && 2 == i is never true. If 1 == i, then 2 != i. If 2 == i, then 1 != i.
1 == i && 2 == i
should be
1 == i || 2 == i
Problem 3
Your loop has 5 passes, but it requires 6!
1) g[0] = v[0];
2) g[1] = v[1];
3) g[2] = v[1]+10;
4) g[3] = v[2]+10;
5) g[4] = v[3]+10;
6) g[5] = v[4]+10;
Solution
#include <stdlib.h>
#include <stdio.h>
int main() {
int v[5] = {2,3,4,5,6};
int g[6];
for( int i = 0; i < sizeof(g)/sizeof(*g); ++i ) {
if ( 0 == i || 1 == i )
g[i] = v[i];
else
g[i] = v[i-1]+10;
printf("%d\n", g[i]);
}
return 0;
}
Note that
if ( 0 == i || 1 == i )
can be simplified to
if ( 2 < i )
Your code has a few problems:
if ( 1 == i && 2 == i) will always return false as a variable cannot be both 1 and 2 at the same time.
Your loop iterator takes values larger than they should; when i becomes 5 and 6, v[i] and g[i] triggers reads to memory locations beyond the respective arrays' memory ranges, which explains the random values in your output.
I think this is what you want:
#include <stdlib.h>
#include <stdio.h>
int main()
{
int i = 0;
int v[5] = {2, 3, 4, 5, 6};
int g[6];
for ( i = 0; i < 6; i++ )
{
if ( i < 2 )
{
g[i] = v[i];
}
else
{
g[i] = ( v[i - 1] + 10 );
}
printf ( "%d\n", g[i] );
}
return 0;
}
Output:
2 3 13 14 15 16
It never enter in the if conditional block because i cannot be 1 and 2 at the same time..
So your code will enter just in else...
and it wil start from index 1;
so in this expresion from else : g[k]=(v[i]+10); --- v[i]=> 3 and when you arrive at index 5 or 6 it is outside of your v array....
for( i = 1; i <= 6; i++ ){
k= i + 1;
if ( 1 == i && 2 == i) //never enter here...
{
g[k]=v[i];
}
else
{
g[k]=(v[i]+10); //index get outside the vector length
}
printf("%d\n",g[k]);
}
Related
I want to make a function that formats a matrix that's passed like this:
1 2 3 6
4 5 6 15
7 8 9 24
12 15 18 45
Into a matrix like this:
1 2 3 | 6
4 5 6 | 15
7 8 9 | 24
=============
12 15 18 | 45
I somewhat got the part with vertical bars, but I have no idea how to do the equals part, here's my take on vertical bar:
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (j == n - 2)
printf("%d | ", mat[i][j]);
else if (j == n - 1)
printf("%d\n", mat[i][j]);
else if (i == n - 1)
printf("%d ", mat[i][j]);
else printf("%d ", mat[i][j]);
Printing === before the last row just ends up like this:
1 2 3 | 6
4 5 6 | 15
7 8 9 | 24
===
12 ===
15 18 | 45
I tried everything, but it failed miserably, any suggestions?
Here is demonstrated a straightforward approach to output your array.
#include <stdio.h>
int main( void )
{
enum { N = 4 };
int a[N][N];
for ( int i = 0; i < N; i++ )
{
a[i][N-1] = 0;
for ( int j = 0; j < N - 1; j++ )
{
a[i][N-1] += a[i][j] = i * N + j + 1;
}
}
for ( int i = 0; i < N; i++ )
{
if ( i == N - 1 )
{
for ( int j = 0; j < 3 * N + 1; j++ )
{
putchar( '=' );
}
putchar( '\n' );
}
for ( int j = 0; j < N; j++ )
{
if ( j != N - 1 )
{
printf( "%-3d", a[i][j] );
}
else
{
printf( "| %-2d", a[i][j] );
}
}
putchar( '\n' );
}
}
The program output is
1 2 3 | 6
5 6 7 | 18
9 10 11 | 30
=============
13 14 15 | 42
You can write a more general function that outputs such an array by using the approach. What you need to do so is to calculate the length of the last element of the array (in the array above the length of the last element 45 is equal to 2) and instead of such a call of printf
printf( "%-3d", a[i][j] );
to use
printf( "%-*d", len + 1, a[i][j] );
so I did a little of modifications on your code like , you outer for loop must loop extra one time to print that = symbol , that's why I used that flag called printedHorizontalLineFlag so that not to go out of array boundaries.
and here is the full edited code :
#include <stdio.h>
void func(int column, int rows, int mat[rows][column])
{
int printedHorizontalLineFlag = 0;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < column; j++) {
if (j == column - 2) {
printf("%d\t| ", mat[i][j]);
}
else if (j == column - 1) {
printf("%d\n", mat[i][j]);
}
else if (printedHorizontalLineFlag == 1 && i == rows - 1) {
printf("%d\t", mat[i][j]);
}
else if (printedHorizontalLineFlag == 0 && i == rows - 1) {
printf("============================\n");
i--;
printedHorizontalLineFlag = 1;
break;
}
else {
printf("%d\t", mat[i][j]);
}
}
}
}
int main()
{
int mat[][4] = {{1, 2, 3, 6},
{4, 5, 6, 15},
{7, 8, 9, 24},
{12, 15, 18, 45}};
func(4, 4, mat);
return 0;
}
and here is image of the output :
I need to find elements of array which are hold in two of three given arrays.
It seems easy, but it's quite dificult and i have been strugling with this for few days.
I hope you can help me..
For input:
1 2 3 5
1 2 4 6 7
1 3 4 8 9 10
Output should be 3 (because 3,4,2 are common for two arrays)
for input
1 2 3 4
2 3 4
3 4 1
Output should be: 2 (because 1 is common for two arrays)
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
int main()
{
int duzina_prvog_niza = 0, duzina_drugog_niza = 0, duzina_treceg_niza = 0; //deklaracija duzina nizova
printf("Unesite broj clanova prvog niza:\n"); // unosimo duzine nizova i elemente nizova
do
{
scanf("%d", &duzina_prvog_niza);
} while (0 > duzina_prvog_niza || duzina_prvog_niza > 50); // mozda ne bi trebalo stavljati gornju granicu za duzinu niza
int niz1[duzina_prvog_niza]; //zavisi kako vam sistem provjere radi, mislim da nece praviti problem
// alociramo niz odgovarajuce duzine, iterativno popunimo niz uz odgovarajucu provjeru
for (int i = 0; duzina_prvog_niza > i; i++)
{
do
{
scanf("%d", &niz1[i]);
} while (0 > niz1[i] || niz1[i] > 10); // citaj elemente sve dok ne ucitas cifre iz odgovarajuceg opsega
}
for (int i = 0; duzina_prvog_niza > i; i++)
printf(" %d ", niz1[i]);
printf("\n");
// ** drugi niz ** -- bilo bi zgodno ovo sve strpati u jednu fju, meni je ovako bilo lakse.. c/p
printf("Unesite broj clanova drugog niza:\n");
do
{
scanf("%d", &duzina_drugog_niza);
} while (0 > duzina_drugog_niza || duzina_drugog_niza > 50);
int niz2[duzina_drugog_niza];
// alociramo niz odgovarajuce duzine, iterativno popunimo niz uz odgovarajucu provjeru
for (int i = 0; duzina_drugog_niza > i; i++)
{
do
{
scanf("%d", &niz2[i]);
} while (0 > niz2[i] || niz2[i] > 10); // citaj elemente sve dok ne ucitas cifre iz odgovarajuceg opsega
}
for (int i = 0; duzina_drugog_niza > i; i++)
printf(" %d ", niz2[i]);
printf("\n");
// ** treci niz **
printf("Unesite broj clanova treceg niza:\n");
do
{
scanf("%d", &duzina_treceg_niza);
} while (0 > duzina_treceg_niza || duzina_treceg_niza > 50);
int niz3[duzina_treceg_niza];
// alociramo niz odgovarajuce duzine, iterativno popunimo niz uz odgovarajucu provjeru
for (int i = 0; duzina_treceg_niza > i; i++)
{
do
{
scanf("%d", &niz3[i]);
} while (0 > niz3[i] || niz3[i] > 10); // citaj elemente sve dok ne ucitas cifre iz odgovarajuceg opsega
}
for (int i = 0; duzina_treceg_niza > i; i++)
printf(" %d ", niz3[i]);
printf("\n");
//pocetna vrijednost brojaca mora biti nula!
int brojac = 0;
int pomocni_brojac = 0;
// (S_1 intersect S_2) union (S_2 intersect S_3) union (S_3 intersect S_1) -- matematicko rjesenje problema
int x;
int pomocni_niz[duzina_prvog_niza + duzina_drugog_niza + duzina_treceg_niza];
for (int i = 0; duzina_prvog_niza + duzina_drugog_niza + duzina_treceg_niza > i; i++)
pomocni_niz[i] = 0;
int max;
if(duzina_prvog_niza>=duzina_drugog_niza && duzina_prvog_niza>=duzina_treceg_niza) max=duzina_prvog_niza;
if(duzina_drugog_niza>=duzina_prvog_niza && duzina_drugog_niza>=duzina_treceg_niza) max=duzina_drugog_niza;
if(duzina_treceg_niza>=duzina_drugog_niza && duzina_treceg_niza>=duzina_prvog_niza) max=duzina_treceg_niza;
//prolazimo kroz sve elemente u sva tri niza i poredimo sve elemente sa svim elementima
for (int i = 0; duzina_prvog_niza > i; i++)
{
for (int j = 0; duzina_drugog_niza > j; j++)
{
for (int k = 0; duzina_treceg_niza > k; k++)
{ // ako je element iz prvog niza jednak elementu iz drugog niza, ili je element
if (((niz1[i] == niz2[j]) && (niz2[j] == niz3[k]) && (niz1[i] == niz3[k])))
1;
else if ((niz1[i] != niz2[j]) && (niz2[j] == niz3[k]) && (niz1[i] != niz3[k]))
pomocni_niz[pomocni_brojac++] = niz2[j];
else if ((niz1[i] == niz2[j]) && (niz2[j] != niz3[k]) && (niz1[i] != niz3[k]))
pomocni_niz[pomocni_brojac++] = niz1[i];
else if ((niz1[i] != niz2[j]) && (niz2[j] != niz3[k]) && (niz1[i] == niz3[k]))
pomocni_niz[pomocni_brojac++] = niz2[j];
}
}
}
int y = 0;
for (int g = 0; pomocni_brojac > g; g++)
{
for (int l = 0; pomocni_brojac > l; l++)
{
if (pomocni_niz[g] == pomocni_niz[l])
y++;
}
if (y == 0)
brojac++;
y = 0;
}
for (int i = 0; brojac > i; i++)
printf("%d ", pomocni_niz[i]);
printf("U dva od tri niza se nalazi %d clanova.", brojac);
return 0;
}
Thanks!
There exists a pretty fast solution to your problem. You will need three more arrays each having a size of 100. Each array will record the frequency of any particular input array. The size of each frequency array is 100 since any input array will only consist of numbers in the range 0-99.
For example:
Input arrays:
A: 1 2 3 5
B: 1 2 4 6 7
C: 1 3 4 8 9 10
Frequency arrays:
0 1 2 3 4 5 6 7 8 9 10
A: 0 1 1 1 0 1 0 0 0 0 0
B: 0 1 1 0 1 0 1 1 0 0 0
C: 0 1 0 1 1 0 0 0 1 1 1
In the frequency arrays section:
The top row denotes number which may be present in any input array and the rows below contains their frequency in each input array..
Algorithm
1 : let frequencyA[100]
2 : let frequencyB[100]
3 : let frequencyC[100]
4 :
5 : for i = 0 to A.length-1
6 : if (frequencyA[A[i]] == 0) frequencyA[A[i]]++
7 : for i = 0 to B.length-1
8 : if (frequencyB[B[i]] == 0) frequencyB[B[i]]++
9 : for i = 0 to C.length-1
10: if (frequencyC[C[i]] == 0) frequencyC[C[i]]++
11:
12: for i = 0 to 99
13: if (frequencyA[i]+frequencyB[i]+frequencyC[i] == 2) Print i
The algorithm is pretty straight forward. The only that lines that deserve some explanation are mentioned below.
Line 5-10:
For each input array, we loop though each of its element and record their frequency. We record the frequency of any particular element only once, that is, if any element repeats in a single array, we will record its frequency only once. This is made sure by the if condition which checks if we have recorded the frequency of any element before or not.
Line 12-13:
We start a loop from 0 to 99 since they are the possible values of the array. In the loop, we check if sum of the frequency in the all the three frequency arrays of any element is 2 or not. If its 2, then that element is present in present exactly twice else not.
Time Complexity
The algorithm has a time complexity of O(A.length + B.length + C.length). It is a linear time complexity which is quite fast.
I can not provide you with any code as I do not code in C a lot. I hope I have helped you. If you face any trouble in understanding my answer, please do comment. I will be happy to update my answer.
For starters always use English words for identifiers. In this case your code will be readable for a larger auditorium. Otherwise it is difficult to read it.
This statement in your program
if (((niz1[i] == niz2[j]) && (niz2[j] == niz3[k]) && (niz1[i] == niz3[k])))
1;
does not make a sense.
If you need to output common elements that are present exactly in two of three arrays then there is no great sense to create a forth array with the size equal to the sum of sizes of the three arrays.
If the arrays can be unsorted and you may not sort the arrays then a straightforward approach can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
void f( const int a1[], size_t n1, const int a2[], size_t n2, const int a3[], size_t n3 )
{
size_t total = 0;
for ( size_t i1 = 0; i1 < n1; i1++ )
{
size_t count = 1;
size_t i2 = 0;
while ( i2 < n2 && a2[i2] != a1[i1] ) i2++;
count += i2 != n2;
size_t i3 = 0;
while ( i3 < n3 && a3[i3] != a1[i1] ) i3++;
count += i3 != n3;
if ( count == 2 )
{
++total;
printf( "%d ", a1[i1] );
}
}
for ( size_t i2 = 0; i2 < n2; i2++ )
{
size_t i1 = 0;
while ( i1 < n1 && a1[i1] != a2[i2] ) i1++;
if ( i1 == n1 )
{
size_t i3 = 0;
while ( i3 < n3 && a3[i3] != a2[i2] ) i3++;
if ( i3 != n3 )
{
++total;
printf( "%d ", a2[i2] );
}
}
}
if ( total != 0 ) putchar( '\n' );
printf( "%zu\n", total );
}
int main(void)
{
int a[] = { 1, 2, 3, 5 };
int b[] = { 1, 2, 4, 6, 7 };
int c[] = { 1, 3, 4, 8, 9, 10 };
size_t n1 = sizeof( a ) / sizeof( *a );
size_t n2 = sizeof( b ) / sizeof( *b );
size_t n3 = sizeof( c ) / sizeof( *c );
f( a, n1, b, n2, c, n3 );
return 0;
}
The program output is
2 3 4
3
I should build a function that gets an array and it's size and return a pointer
to new array (i need do create new array by using malloc and realloc) that find the identical numbers and duplicates them in the row
for example the array:{1,8,8,70,2,2,2,5,5,2} and size 10 suppose to return a pointer to this array
{1,8,8,8,8,70,2,2,2,2,2,2,5,5,5,5,2}. Any clue what's wrong with my code??
int * duplicateArray(int* arr, int n)
{
int g = 1;
int i,j=0;
int *p = (int*)(calloc)(n, sizeof(int));
assert(p);
for (i = 0; i < n-1; i++)
{
if (arr[i] == arr[i + 1])
{
p= (int*)(realloc)(p, n+g * sizeof(int));
n=n+g;
assert(p);
p[j] = arr[i];
j++;
p[j] = arr[i+1];
}
else
p[j] = arr[i];
j++;
}
return p;
}
The approach used by you when the memory is constantly reallocated is inefficient.
Also the function should return not only the pointer to the dynamically allocated array but also the number of elements in the allocated array. Otherwise the user of the function will not know how many elements are in the allocated array. To use a sentinel value for an integer dynamically allocated array is not a good idea.
I suggest to split the task into two separate tasks that will correspond to two separate functions..
The first function will count the number of repeated elements in a given array.
The second function will create dynamically an array with the specified size based on the returned value of the first function and copy elements of the source array to the newly created array.
Here is a demonstrative program
#include <stdio.h>
#include <stdlib.h>
size_t countRepeated( const int a[], size_t n )
{
size_t repeated = 0;
for ( size_t i = 0; i != n; )
{
size_t m = 1;
while ( ++i != n && a[i] == a[i-1] ) ++m;
if ( m != 1 ) repeated += m;
}
return repeated;
}
int * copyWithDuplication( const int a[], size_t n, size_t m )
{
int *result = m == 0 ? NULL : calloc( m, sizeof( int ) );
if ( result )
{
for ( size_t i = 0, j = 0; j != m && i != n; )
{
result[j++] = a[i++];
size_t k = 1;
while ( j != m && i != n && a[i] == a[i-1] )
{
result[j++] = a[i++];
++k;
}
if ( k != 1 )
{
while ( j != m && k-- ) result[j++] = a[i-1];
}
}
}
return result;
}
int main(void)
{
int a[] = { 1, 8, 8, 70, 2, 2, 2, 5, 5, 2 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
size_t m = N + countRepeated( a, N );
int *b = copyWithDuplication( a, N, m );
if ( b )
{
for ( size_t i = 0; i < m; i++ )
{
printf( "%d ", b[i] );
}
putchar( '\n' );
}
free( b );
return 0;
}
The program output is
1 8 8 70 2 2 2 5 5 2
1 8 8 8 8 70 2 2 2 2 2 2 5 5 5 5 2
And here is another more interesting demonstrative program.
#include <stdio.h>
#include <stdlib.h>
size_t countRepeated( const int a[], size_t n )
{
size_t repeated = 0;
for ( size_t i = 0; i != n; )
{
size_t m = 1;
while ( ++i != n && a[i] == a[i-1] ) ++m;
if ( m != 1 ) repeated += m;
}
return repeated;
}
int * copyWithDuplication( const int a[], size_t n, size_t m )
{
int *result = m == 0 ? NULL : calloc( m, sizeof( int ) );
if ( result )
{
for ( size_t i = 0, j = 0; j != m && i != n; )
{
result[j++] = a[i++];
size_t k = 1;
while ( j != m && i != n && a[i] == a[i-1] )
{
result[j++] = a[i++];
++k;
}
if ( k != 1 )
{
while ( j != m && k-- ) result[j++] = a[i-1];
}
}
}
return result;
}
int main(void)
{
int a[] = { 1, 8, 8, 70, 2, 2, 2, 5, 5, 2 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
size_t m = N + countRepeated( a, N );
for ( size_t i = 0; i < m; i++ )
{
int *b = copyWithDuplication( a, N, i + 1 );
if ( b )
{
for ( size_t j = 0; j < i + 1; j++ )
{
printf( "%d ", b[j] );
}
putchar( '\n' );
}
free( b );
}
return 0;
}
Its output is
1 8 8 70 2 2 2 5 5 2
1
1 8
1 8 8
1 8 8 8
1 8 8 8 8
1 8 8 8 8 70
1 8 8 8 8 70 2
1 8 8 8 8 70 2 2
1 8 8 8 8 70 2 2 2
1 8 8 8 8 70 2 2 2 2
1 8 8 8 8 70 2 2 2 2 2
1 8 8 8 8 70 2 2 2 2 2 2
1 8 8 8 8 70 2 2 2 2 2 2 5
1 8 8 8 8 70 2 2 2 2 2 2 5 5
1 8 8 8 8 70 2 2 2 2 2 2 5 5 5
1 8 8 8 8 70 2 2 2 2 2 2 5 5 5 5
1 8 8 8 8 70 2 2 2 2 2 2 5 5 5 5 2
Any clue what's wrong with my code??
If the parameter n is 1, then your program will allocate an array for 1 element of type int, but will write nothing to it. It won't copy anything from the input buffer.
You are accessing both the input arr and the output array p out of bounds, which causes undefined behavior. The loop
for (i = 0; i < n-1; i++)
will not count from 0 to the function parameter n minus 2, because n is being incremented inside the loop. This causes your loop to have more iterations than it is supposed to, which causes both the input and the output array to be accessed out of bounds.
Also, there doesn't seem to be much point in your variable g, as it never changes and always has the value 1.
The function prototype
int * duplicateArray(int* arr, int n);
does not seem meaningful, as the calling function has no way of knowing the size of the returned array. If you use the function prototype
void duplicateArray ( const int *p_input_array, int num_input, int **pp_output_array, int *p_num_output );
instead, the function duplicateArray can write the address of the new array to *pp_output_array and the number of elements in the array to *p_num_output. That way, the calling function will effectively be able to receive two "return values" instead of only one.
Here is my implementation of the function duplicateArray and also of the calling function:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
void duplicateArray( const int *p_input_array, int num_input, int **pp_output_array, int *p_num_output )
{
int i = 0, j = 0;
// In the most extreme case, the output array must be 2 times larger than
// the input buffer, so we allocate double the size of the input buffer.
int *p_output_array = (int*)malloc( num_input * 2 * sizeof(int) );
assert( p_output_array != NULL );
while ( i < num_input )
{
int num_repetitions;
int k = p_input_array[i++];
//count the number of repetitions
for ( num_repetitions = 0; i < num_input && p_input_array[i] == k; num_repetitions++, i++ );
if ( num_repetitions == 0 )
{
p_output_array[j++] = k;
}
else
{
for ( int l = 0; l < num_repetitions + 1; l++ )
{
p_output_array[j++] = k;
p_output_array[j++] = k;
}
}
}
//shrink the array to the actually needed size
p_output_array = (int*)realloc( p_output_array, j * sizeof(int) );
assert( p_output_array != NULL );
*pp_output_array = p_output_array;
*p_num_output = j;
}
int main()
{
int arr[] = { 1, 8, 8, 70, 2, 2, 2, 5, 5, 2 };
int *p;
int num;
duplicateArray( arr, sizeof(arr)/sizeof(*arr), &p, &num );
for ( int i = 0; i < num; i++ ) {
printf( "%d\n", p[i] );
}
free( p );
}
So today i tried to implement a quicksort. It's almost working but somehow skips one element.
example : 5 2 8 2 3 4 1 5 7 -5 -1 -9 2 4 5 7 6 1 4
output : -5 -1 -9 1 2 2 3 2 1 4 4 4 5 5 5 6 7 7 8
In this case it skips -9. Here is code of the function.
test = quicksort_asc(0,size,tab,size) // this is function call
int quicksort_asc(int l, int r, int tab[], int tabSize) //l is first index, r is last index, tabSize is tabsize-1 generally
{
int i,buffer,lim,pivot,flag=0;
if(l == r)
return 0;
lim = l-1;
pivot = tab[r-1];
printf("pivot:%d\n",pivot);
for (i = l; i <= r-1; ++i)
{
if(tab[i] < pivot) {
lim++;
buffer = tab[lim];
tab[lim] = tab[i];
tab[i] = buffer;
flag = 1;
}
}
if(flag == 0)
return 0;
buffer = tab[lim+1];
tab[lim+1] = pivot;
tab[r-1] = buffer;
quicksort_asc(l,lim+1,tab,lim+1);//left side
quicksort_asc(lim+1,tabSize,tab,tabSize);//right side
}
This is my array length count code. 100 is maximum size, 0 is a stop value.
Count is size.
int count=0;
for (int i = 0; i < 100; i++)
{
test = scanf("%d",&vec[i]);
if(vec[i] == 0) break;
count++;
}
return count;
It seems nobody hurries to help you.:)
For starters the last parameter is redundant.
int quicksort_asc(int l, int r, int tab[], int tabSize);
^^^^^^^^^^^
All you need is the pointer to the first element of the array and starting and ending indices.
Also instead of the type int for the indices it is better to use the type size_t. However as you are using the expression statement
lim = l-1;
then o'k let the indices will have the type int though you could use another approach without this expression statement.
So the function should be declared like
void quicksort_asc( int tab[], int l, int r );
The variable flag is redundant. When it is equal to 0 it means that all elements before the pivot value are greater than or equal to it. But nevertheless you have to swap the pivot value with the first element that is greater than or equal to the pivot.
This loop
for (i = l; i <= r-1; ++i)
has one iteration redundant. It should be set like
for (i = l; i < r-1; ++i)
This call
quicksort_asc(lim+1,tabSize,tab,tabSize);
^^^^^ ^^^^^^^
shall be substituted for this call
quicksort_asc( lim + 2, r, tab );
^^^^^^^ ^^
because the pivot value is not included in this sub-array.
Here is a demonstrative program.
#include <stdio.h>
void quicksort_asc( int tab[], int l, int r )
{
if ( l + 1 < r )
{
int lim = l - 1;
int pivot = tab[r - 1];
for ( int i = l; i < r - 1; ++i )
{
if ( tab[i] < pivot )
{
lim++;
int tmp = tab[lim];
tab[lim] = tab[i];
tab[i] = tmp;
}
}
tab[r - 1] = tab[lim + 1];
tab[lim + 1] = pivot;
quicksort_asc( tab, l, lim + 1 );
quicksort_asc( tab, lim + 2, r );
}
}
int main(void)
{
int a[] = { 5, 2, 8, 2, 3, 4, 1, 5, 7, -5, -1, -9, 2, 4, 5, 7, 6, 1, 4 };
const int N = ( int )( sizeof( a ) / sizeof( *a ) );
for ( int i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
quicksort_asc( a, 0, N );
for ( int i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
Its output is
5 2 8 2 3 4 1 5 7 -5 -1 -9 2 4 5 7 6 1 4
-9 -5 -1 1 1 2 2 2 3 4 4 4 5 5 5 6 7 7 8
I'm writing a function that takes an input n and creates a 1D array of size (2n-1)^2 to simulate a square. I.e. for an input of n = 1, there is just one point, for an input of n = 2, it would look like
0 1 2
3 4 5
6 7 8
and for n = 3 it would look like
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
where each number is a point.
The function terminates when the current location is detected at being on an edge and the point attempts to move off of the square's grid.
The purpose of this is to simulate how many points are visited for squares of different sizes, from n=2^0 up to n=2^8 and to return the fraction of how many points are visited over the total amount of points in the square.
The function generates a random number and checks the modulus of it against 4, and if it returns 0, the location is moved up 1, if it returns 1, the location is moved right, 2 goes down, and 3 goes left.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double two_d_random (int n) {
int tot_points = (2 * n - 1)*(2 * n - 1);
int value = (n*n)+((n-1)*(n-1))-1; //center
int length = 2 * n - 1; //length of side
int *array = (int *)malloc (sizeof (int) * tot_points);
int count = 0;
array[value] = 1;
while (1 == 1) {
int r = rand () % 4;
array[value] = 1;
if (r == 0) {//UP
if ((value >= 0) && (value < length)) {
goto a;
}
else {
array[value] = 1;
value -= length;
}
}
else if (r == 1) {//RIGHT
if ((value % length) == (2*n-2)){
goto a;
}
else {
array[value] = 1;
value += 1;
}
}
else if (r == 2) {//DOWN
if ((value < tot_points) && (value >= (tot_points - length))) {
goto a;
}
else {
array[value] = 1;
value += length;
}
}
else if (r == 3) {//LEFT
if (value % length == 0) {
goto a;
}
else {
array[value] = 1;
value -= 1;
}
}
}
a:
for (int i = 0; i < tot_points; i++) {
if (array[i] == 1) {
count += 1;
}
}
free (array);
return 1.0 * count / tot_points;
}
int main ()
{
int trials = 1000;
srand (12345);
for (int n = 1; n <= 256; n *= 2)
{
double sum = 0.;
for (int i = 0; i < trials; i++)
{
double p = two_d_random(n);
sum += p;
}
printf ("%d %.3lf\n", n, sum / trials);
}
return 0;
}
My current problem is that while I run it on my machine, I get a range of values I'm not expecting:
However, when a colleague runs it on their machine, they get the following which is what I expected:
I realize this is a large amount to ask at one point. I also realize that I should not use goto. I've put a lot of time into this however and I've no idea how to fix this. Any help is greatly appreciated.
You need to initialise your array. When calling malloc() it just returns a chunk of un-initialised memory. Either initialise it, or use calloc() instead, to get pre-zeroed memory.
double two_d_random( int n )
{
int tot_points = ( 2 * n - 1 ) * ( 2 * n - 1 );
int value = ( n * n ) + ( ( n - 1 ) * ( n - 1 ) ) - 1; //center
int length = 2 * n - 1; //length of side
int *array = (int *) malloc( sizeof( int ) * tot_points );
int count = 0;
// Initialise the array to zero
for ( int i=0; i<tot_points; i++ )
{
array[i] = 0;
}
array[value] = 1;
while ( 1 == 1 )
{
int r = rand() % 4;
array[value] = 1;
if ( r == 0 )
With this modification, I get results similar to what you reported as desired:
1 1.000
2 0.367
4 0.221
8 0.154
16 0.122
32 0.101
64 0.085
128 0.077
256 0.071