This is my code:
int i=1 , j=1 ,k=0, n=1;
printf("\nPut in number n which is the upper limit: ");
scanf("%d", &n);
bool *eratos = malloc(sizeof(n));
for (int m = 1; m<=n; m++) {
printf("%d,", m);
eratos[m] = m;
printf("%d,", eratos[m]);
}
For some reason it does not fill up the eratos[m] array with numbers from 1 to 50 but only withs ones.
This is my output:
1,1,2,1,3,1,4,1,5,1,6,1,7,1,8,1,9,1,10,1,11,1,12,1,13,1,14,1,15,1,16,1,17,1,18,1,19,1,20,1,21,1,22,1,23,1,24,1,25,1,26,1,27,1,28,1,29,1,30,1,31,1,32,1,33,1,34,1,35,1,36,1,37,1,38,1,39,1,40,1,41,1,42,1,43,1,44,1,45,1,46,1,47,1,48,1,49,1,50,1
The first line of printf() is to check whether its counting up correctly, which it does obviously. But the array gets only filled up with ones and not with [1,2,3…50].
First of all, a bool cannot hold anything apart from a 0 and 1. To have values other than that, use int type.
That said, the next problem is in the memory allocation, you need to allocate appropriate amount of memory, i.e., the amount (value) held by n, not equal to the size of the variable n itself.
int *eratos = malloc(n * sizeof(*eratos));
Finally, you need to correct your for loop to avoid off by one error, like
for (int m = 0; m < n; m++) { // C arrays use 0-based-indexing
printf("%d,", m+1); // still counts from 1, for sake of printing
Another issue apart from the issue pointed out by SouravGosh is you have taken the bool array.
bool *eratos = malloc(sizeof(n));
eratos[m] = m;
Any non zero value is true in case of bool.
And anther issue is that array indexes start at 0, not at 1. Do:
for (int m = 0; m < n; m++)
For starters this memory allocation
bool *eratos = malloc(sizeof(n));
does not make a sense. The expression sizeof( n ) is equal to the expression sizeof( int ) and does not depend on the value stored in the variable n.
You declared an array with the element type bool that is an alias for the type _Bool. Any non-zero value is converted to the value 1.
Also this loop
for (int m = 1; m<=n; m++) {
printf("%d,", m);
eratos[m] = m;
printf("%d,", eratos[m]);
}
invokes undefined behavior because the valid range of indices for an array with n elements is [0, n).
It seems what you need is the following
unsigned int n = 1;
printf("\nPut in number n which is the upper limit: ");
scanf("%u", &n);
unsigned int *eratos = malloc( n * sizeof( unsigned int ) );
for ( unsigned int i = 0; i < n; i++ )
{
printf("%u,", i + 1 );
eratos[i] = i + 1;
printf("%u,", eratos[i]);
}
You have multiple problems in your code.
First you say that eratos is a pointer to bool when you seem to want an array of int.
This is solved by changing the type to pointer to int:
int *eratos = ...;
Then since n is an int, sizeof(n) is the same as sizeof(int), which is typically equal to 4. That is, you only allocate four bytes for your array.
You need to allocate n elements, which is n multiplied by the size of each element (which would be sizeof *eratos):
int *eratos = malloc(n * sizeof *eratos);
Lastly, remember that array indexes in C are zero based, which means an array of n elements will have indexes from 0 to n - 1 (inclusive). Which means eratos[m] will go out of bounds (when m == n).
This can be solved in two ways:
Either subtract 1 for the array index:
for (int m = 1; m <= n; ++m)
{
eratos[m - 1] = m;
}
Or loop from 0 to n - 1 and add 1 to m to get the "natural number":
for (int m = 0; m < n; ++m)
{
eratos[m] = m + 1;
}
On an unrelated note, if you're only supposed to print the numbers between 1 and n (inclusive) then you don't need the array, only a single printf statement in the loop:
for (int m = 1; m <= n; ++m)
{
printf("%d,", m);
}
Related
So here is the function:
int VerifTri(int t[], int g[], int n, int m)
{ int k, l; int sorted, sorted2;
sorted = 1; sorted2 = 1;
for (k=0; k<n; k++)
{
if( t[k] > t[k+1] )
sorted=0;
}
for (l=0; l<m; l++)
{
if (g[l] > g[l+1])
{
sorted2=0;
}
}
if ((sorted == 1) && (sorted2 == 1))
return 1;
else
return 0;
}
There is no syntax error, but the code is just wrong: I used it in a program and I entered two sorted arrays and it still returned 0.
Assuming that n is a length of t and m is a length of g you can put
int VerifTri(int t[], int g[], int n, int m)
{
int k;
for (k = 0; k < n - 1; k++)
if ( t[k] > t[k+1] )
return 0;
for (k = 0; k < m - 1; k++)
if ( g[k] > g[k+1] )
return 0;
return 1;
}
Please, note the range: k == [0 .. n - 1) otherwise the last comparison will be incorrect one
t[n - 1] > t[n]
Same for g array
When we found any array being unsorted we can return 0: if an array is not sorted, both of them can't be sorted
what is wrong with this function i wrote to see if two arrays are
sorted in ascending order, in C?
The function is initially wrong independent of its body because there is no great sense to define such a function instead of defining a function that checks whether an array is sorted.
Having such a function you can check in the caller whether two arrays are sorted the following way
int sorted = VerifTri( t, n ) && VerifTri( g, m );
Or you can even check whether three arrays are sorted like
int sorted = VerifTri( a1, n1 ) && VerifTri( a2, n2 ) && VerifTri( a3, n3 );
Moreover the parameters of the function that denote arrays should have qualifier const because the passed arrays are not changed within the function. And the parameters that denote sizes of the arrays should have the type size_t.
Within the for loops there is an attempt to access memory beyond the arrays in these if statements
if( t[k] > t[k+1] )
and
if (g[l] > g[l+1])
when k is equal to n-1 or when l is equal to m-1.
And the loops should be interrupted as soon as a previous element of the array is greater than the next element of the array.
So your function should look for example the following way
int VerifTri( const int a[], size_t n )
{
size_t i = 0;
if ( i != n )
{
while ( ++i < n && !( a[i] < a[i-1] ) );
}
return i == n;
}
And if you want to check whether two arrays are sorted then you can just write as shown above the expression
VerifTri( t, n ) && VerifTri( g, l )
If you want to check whether one of the arrays is sorted then you can write the expression
VerifTri( t, n ) || VerifTri( g, l )
Using your original function you will be unable to do this and have to write one more function.
There are some problems in your code, some benign, some major:
the code is badly indented: this makes it hard to read, with more places for bugs to hide.
the loops are incorrect: assuming n is the length of t and m is the length of g, the last comparison will reference an element beyond the end of the arrays.
the code is inefficient: you could return 0 as soon as any comparison evaluates to false.
the name l for a variable is risky as it looks dangerously similar to 1 in common fixed width fonts.
the prototype could be improved: the array pointers should be defined as const since the function does not modify their contents.
your function is too specific: calling a simpler function that checks a single array is simpler and less confusing.
Here is a modified version:
int VerifTri(const int t[], const int g[], int n, int m) {
for (int i = 1; i < n; i++) {
if (t[i - 1] > t[i])
return 0;
}
for (int i = 1; i < m; i++) {
if (g[i - 1] > g[i])
return 0;
}
return 1;
}
For illustration, here is a simpler function to test a single array:
int VerifTri(const int *t, size_t n) {
for (; n --> 1; t++) {
if (t[0] > t[1])
return 0;
}
return 1;
}
So basically according to definition of array we cannot change array size. But if I am adding element to a same array by shifting other elements to the right of array, so the array size is going to increase.
How this is possible?
#include<stdio.h>
int main() {
int n, j, k, item;
printf("Enter size of array:\n");
scanf("%d", &n);
printf("Enter element to insert and position of element:\n");
scanf("%d,%d", &item, &k);
int a[n];
for (j = 0; j < n; j++) {
printf("Enter a[%d] element:\n", j);
scanf("%d", &a[j]);
}
j = n - 1;
while (j >= k - 1) {
a[j + 1] = a[j];
j = j - 1;
}
a[k - 1] = item;
for (j = 0; j <= n; j++) {
printf("%d\n", a[j]);
}
}
Shifting the contents of the array to the right will not resize the array. If the array was not already large enough to hold the result of the shift, then you have overrun the array object, and have induced undefined behavior.
There is no way to dynamically increase the size of a variable with static or auto duration (e.g., global or local variables), and this includes arrays. If your compiler supports variable length arrays (VLAs), changing the value of the expression controlling the dimension of the array does not affect the array's size.
int main (void) {
int n = 3;
int v[n];
printf("%zu\n", sizeof(v));
++n;
printf("%zu\n", sizeof(v));
}
The program above will print the same value twice.
I am not entirely sure what you're asking, but for any readers interested in knowing how to dynamically change the size of an array in C: if an array is declared in stack memory, its size cannot change. However, a block of memory intended to be used as an array is declared on the heap (i.e. with malloc or calloc), can be reallocated with a different size if necessary:
int *data = malloc(10 * sizeof(int)), *data2 = NULL;
int i;
if(data == NULL)
{
perror("malloc");
exit(EXIT_FAILURE);
}
for (i = 0; i < 10; i++)
{
data[i] = i;
}
data2 = realloc(data, 11 * sizeof(int));
if(data2 == NULL)
{
free(data);
perror("realloc");
exit(EXIT_FAILURE);
}
else
{
data = data2;
}
data[10] = 10;
for (i = 0; i < 11; i++)
printf("%d ", data[i]);
free(data);
data = NULL;
Shifting elements in an array down one element will not change its size.
If you declare an array as
T a[N]; // assume N is a constant expression
then a can only ever hold N elements of type T - no more, no less. You cannot add extra elements to the array, nor can you remove elements from the array.
However...
C does not force any bounds checking on array subscripting, so it's possible that you can read or write past the end of the array such as
a[N + 2] = x;
The behavior on doing so is undefined - your program may work as expected, or it may crash immediately, or you may corrupt other objects in the program. The runtime environment will (most likely) not throw an IndexOutOfBounds-type exception.
There is a thing called a variable-length array that was added in C99, where the array size is not a constant expression:
size_t size = some_value();
T a[size];
Variable length arrays are only variable length in the sense that their size isn't determined until runtime - however, once defined, their size is fixed throughout their lifetime, and like regular arrays, they cannot grow as new items are added.
If you dynamically allocate a chunk of memory using
T *a = malloc( sizeof *a * some_size );
then you can grow or shrink that chunk of memory using realloc:
T *tmp = realloc( a, sizeof *a * (some_size * 2) );
if ( tmp )
{
a = tmp;
some_size *= 2;
}
.... array we cannot change .. But if I (do something special) ... the array size is going to increase.
How this is possible?
Undefined behavior
Arrays cannot change size once defined.
Code attempts to assign a[j + 1] with j = n-1 and that is a[n]. This is outside array a[] and so undefined behavior. Rest of code is irrelevant for at that point anything is possible, code crash, error report, even apparent successful array expansion, etc.
int a[n];
...
j = n - 1;
while (j >= k - 1) {
a[j + 1] = a[j]; // To attempt access to `a[n]` is UB
Hi i need to check if the array is symmetry or not. i have a function that takes in a two-dimensional array of integer numbers M and the array sizes for rows and columns as parameters, and returns 1 if M is symmetric or 0 otherwise. I tried many times but the output will be either yes to non-symmetric array or no to symmetric array
Here is my code:
#include <stdio.h>
#define SIZE 10
#define INIT_VALUE -1
int symmetry2D(int M[][SIZE], int rowSize, int colSize);
int main()
{
int M[SIZE][SIZE], i, j, result = INIT_VALUE;
int rowSize, colSize;
printf("Enter the array size (rowSize, colSize): \n");
scanf("%d %d", &rowSize, &colSize);
printf("Enter the matrix (%dx%d): \n", rowSize, colSize);
for (i = 0; i < rowSize; i++)
for (j = 0; j < colSize; j++)
scanf("%d", &M[i][j]);
result = symmetry2D(M, rowSize, colSize);
if (result == 1)
printf("symmetry2D(): No\n");
else if (result == 0)
printf("symmetry2D(): Yes\n");
else
printf("Error\n");
return 0;
}
int symmetry2D(int M[][SIZE], int rowSize, int colSize)
{
int h, k, temp;
int result;
for (h = 0; h < rowSize; h++)
{
for (k = 0; k < colSize; k++)
{
M[h][k] = M[k][h];
}
}
result = 0;
for (h = 0; h < rowSize && result; h++)
{
for (k = 0; k < colSize; k++)
{
//if it is not equal to its transpose
if (M[h][k] != M[h][k])
{
result = 1;
break;
}
}
}
if (result == 0)
{
for (h = 0; h < rowSize; h++)
{
for (k = 0; k < colSize; k++)
{
return result = 0;
}
}
}
else
return result = 1;
}
Several issues:
By your definition, a matrix is symmetric if and only if it is equal to its transpose. That can be the case only for square matrices, yet you accommodate non-square matrices as well, for no apparent reason.
Your symmetry2D() function contains serious logical flaws:
It makes the input symmetric via the loop that performs M[h][k] = M[k][h]
Even if it did not do so, it would never find the input non-symmetric, because its test for that is if (M[h][k] != M[h][k]), which must always fail.
It's unclear what you think the if/else and loop nest at the end of symmetry2D() are achieving for you, but provided that rowSize and colSize are both greater than zero, the actual effect of the whole construct is the same as a simple return result;.
It looks like the idea might have been to create an array containing the transpose of the input, and then compare the input to that. That would have worked, despite being rather grotesquely inefficient, but you never in fact create that separate array for the transpose. If you're going to test without creating the transpose -- which you should -- then
Do not modify the input array (so remove the first loop nest altogether).
Get your indexing right for the symmetry comparisons: M[h][k] != M[k][h]
For best efficiency, avoid redundant and needless comparisons. For example, if you have already tested the M[1][2] == M[2][1] then you do not need to test whether M[2][1] == M[1][2]. And you never need to test elements on the main diagonal. You could achieve this efficiency pretty easily with a better choice of loop bounds.
Also, if indeed the symmetry2D() function is supposed to avoid modifying the input array, consider declaring the element type for its first argument to be const int instead of plain int (but do not modify the type of the corresponding variable in main()). If you had written it that way in the first place then the compiler would have noticed the function's logically erroneous attempt to modify the array elements, and rejected the code.
Could you explain me how the following two algorithms work?
int countSort(int arr[], int n, int exp)
{
int output[n];
int i, count[n] ;
for (int i=0; i < n; i++)
count[i] = 0;
for (i = 0; i < n; i++)
count[ (arr[i]/exp)%n ]++;
for (i = 1; i < n; i++)
count[i] += count[i - 1];
for (i = n - 1; i >= 0; i--)
{
output[count[ (arr[i]/exp)%n] - 1] = arr[i];
count[(arr[i]/exp)%n]--;
}
for (i = 0; i < n; i++)
arr[i] = output[i];
}
void sort(int arr[], int n)
{
countSort(arr, n, 1);
countSort(arr, n, n);
}
I wanted to apply the algorithm at this array:
After calling the function countSort(arr, n, 1) , we get this:
When I call then the function countSort(arr, n, n) , at this for loop:
for (i = n - 1; i >= 0; i--)
{
output[count[ (arr[i]/exp)%n] - 1] = arr[i];
count[(arr[i]/exp)%n]--;
}
I get output[-1]=arr[4].
But the array doesn't have such a position...
Have I done something wrong?
EDIT:Considering the array arr[] = { 10, 6, 8, 2, 3 }, the array count will contain the following elements:
what do these numbers represent? How do we use them?
Counting sort is very easy - let's say you have an array which contains numbers from range 1..3:
[3,1,2,3,1,1,3,1,2]
You can count how many times each number occurs in the array:
count[1] = 4
count[2] = 2
count[3] = 3
Now you know that in a sorted array,
number 1 will occupy positions 0..3 (from 0 to count[1] - 1), followed by
number 2 on positions 4..5 (from count[1] to count[1] + count[2] - 1), followed by
number 3 on positions 6..8 (from count[1] + count[2] to count[1] + count[2] + count[3] - 1).
Now that you know final position of every number, you can just insert every number at its correct position. That's basically what countSort function does.
However, in real life your input array would not contain just numbers from range 1..3, so the solution is to sort numbers on the least significant digit (LSD) first, then LSD-1 ... up to the most significant digit.
This way you can sort bigger numbers by sorting numbers from range 0..9 (single digit range in decimal numeral system).
This code: (arr[i]/exp)%n in countSort is used just to get those digits. n is base of your numeral system, so for decimal you should use n = 10 and exp should start with 1 and be multiplied by base in every iteration to get consecutive digits.
For example, if we want to get third digit from right side, we use n = 10 and exp = 10^2:
x = 1234,
(x/exp)%n = 2.
This algorithm is called Radix sort and is explained in detail on Wikipedia: http://en.wikipedia.org/wiki/Radix_sort
It took a bit of time to pick though your countSort routine and attempt to determine just what it was you were doing compared to a normal radix sort. There are some versions that split the iteration and the actual sort routine which appears to be what you attempted using both countSort and sort functions. However, after going though that exercise, it was clear you had just missed including necessary parts of the sort routine. After fixing various compile/declaration issues in your original code, the following adds the pieces you overlooked.
In your countSort function, the size of your count array was wrong. It must be the size of the base, in this case 10. (you had 5) You confused the use of exp and base throughout the function. The exp variable steps through the powers of 10 allowing you to get the value and position of each element in the array when combined with a modulo base operation. You had modulo n instead. This problem also permeated you loop ranges, where you had a number of your loop indexes iterating over 0 < n where the correct range was 0 < base.
You missed finding the maximum value in the original array which is then used to limit the number of passes through the array to perform the sort. In fact all of your existing loops in countSort must fall within the outer-loop iterating while (m / exp > 0). Lastly, you omitted a increment of exp within the outer-loop necessary to applying the sort to each element within the array. I guess you just got confused, but I commend your effort in attempting to rewrite the sort routine and not just copy/pasting from somewhere else. (you may have copied/pasted, but if that's the case, you have additional problems...)
With each of those issues addressed, the sort works. Look though the changes and understand what it is doing. The radix sort/count sort are distribution sorts relying on where numbers occur and manipulating indexes rather than comparing values against one another which makes this type of sort awkward to understand at first. Let me know if you have any questions. I made attempts to preserve your naming convention throughout the function, with the addition of a couple that were omitted and to prevent hardcoding 10 as the base.
#include <stdio.h>
void prnarray (int *a, int sz);
void countSort (int arr[], int n, int base)
{
int exp = 1;
int m = arr[0];
int output[n];
int count[base];
int i;
for (i = 1; i < n; i++) /* find the maximum value */
m = (arr[i] > m) ? arr[i] : m;
while (m / exp > 0)
{
for (i = 0; i < base; i++)
count[i] = 0; /* zero bucket array (count) */
for (i = 0; i < n; i++)
count[ (arr[i]/exp) % base ]++; /* count keys to go in each bucket */
for (i = 1; i < base; i++) /* indexes after end of each bucket */
count[i] += count[i - 1];
for (i = n - 1; i >= 0; i--) /* map bucket indexes to keys */
{
output[count[ (arr[i]/exp) % base] - 1] = arr[i];
count[(arr[i]/exp)%n]--;
}
for (i = 0; i < n; i++) /* fill array with sorted output */
arr[i] = output[i];
exp *= base; /* inc exp for next group of keys */
}
}
int main (void) {
int arr[] = { 10, 6, 8, 2, 3 };
int n = 5;
int base = 10;
printf ("\n The original array is:\n\n");
prnarray (arr, n);
countSort (arr, n, base);
printf ("\n The sorted array is\n\n");
prnarray (arr, n);
printf ("\n");
return 0;
}
void prnarray (int *a, int sz)
{
register int i;
printf (" [");
for (i = 0; i < sz; i++)
printf (" %d", a[i]);
printf (" ]\n");
}
output:
$ ./bin/sort_count
The original array is:
[ 10 6 8 2 3 ]
The sorted array is
[ 2 3 6 8 10 ]
I saw an interview question which asked to
Interchange arr[i] and i for i=[0,n-1]
EXAMPLE :
input : 1 2 4 5 3 0
answer :5 0 1 4 2 3
explaination : a[1]=2 in input , so a[2]=1 in answer so on
I attempted this but not getting correct answer.
what i am able to do is : for a pair of numbers p and q , a[p]=q and a[q]=p .
any thoughts how to improve it are welcome.
FOR(j,0,n-1)
{
i=j;
do{
temp=a[i];
next=a[temp];
a[temp]=i;
i=next;
}while(i>j);
}
print_array(a,i,n);
It would be easier for me to to understand your answer if it contains a pseudocode with some explaination.
EDIT : I came to knpw it is cyclic permutation so changed the question title.
Below is what I came up with (Java code).
For each value x in a, it sets a[x] to x, and sets x to the overridden value (to be used for a[a[x]]), and repeats until it gets back to the original x.
I use negative values as a flag to indicate that the value's already been processed.
Running time:
Since it only processes each value once, the running time is O(n).
Code:
int[] a = {1,2,4,5,3,0};
for (int i = 0; i < a.length; i++)
{
if (a[i] < 0)
continue;
int j = a[i];
int last = i;
do
{
int temp = a[j];
a[j] = -last-1;
last = j;
j = temp;
}
while (i != j);
a[j] = -last-1;
}
for (int i = 0; i < a.length; i++)
a[i] = -a[i]-1;
System.out.println(Arrays.toString(a));
Here's my suggestion, O(n) time, O(1) space:
void OrderArray(int[] A)
{
int X = A.Max() + 1;
for (int i = 0; i < A.Length; i++)
A[i] *= X;
for (int i = 0; i < A.Length; i++)
A[A[i] / X] += i;
for (int i = 0; i < A.Length; i++)
A[i] = A[i] % X;
}
A short explanation:
We use X as a basic unit for values in the original array (we multiply each value in the original array by X, which is larger than any number in A- basically the length of A + 1). so at any point we can retrieve the number that was in a certain cell of the original array by array by doing A[i] / X, as long as we didn't add more than X to that cell.
This lets us have two layers of values, where A[i] % X represents the value of the cell after the ordering. these two layers don't intersect through the process.
When we finished, we clean A from the original values multiplied by X by performing A[i] = A[i] % X.
Hopes that's clean enough.
Perhaps it is possible by using the images of the input permutation as indices:
void inverse( unsigned int* input, unsigned int* output, unsigned int n )
{
for ( unsigned int i = 0; i < n; i++ )
output[ input[ i ] ] = i;
}