Algorithms for deleting multiple elements in arrays in C - c

I am trying to learn C and I am trying to write a piece of code which does the following:
Take user input of a natural number n
Take user input of n elements and store them in the array x
Delete all negative numbers from the array x
Print the new array, with the length n - number of deleted elements
Here is my code:
#include <stdio.h>
int main(void)
{
int n, i, count=0;
double x[1000];
scanf("%d", &n);
for (i=0; i<n; i++)
scanf("%lg", &x[i]);
for (i=0; i<n; i++)
{
if (x[i] < 0)
{
count++;
continue;
};
x[i-count]=x[i];
};
n -= count;
for (i=0; i<n; i++)
printf("%d: %g\n", i, x[i]);
return 0;
}
I have been told that I should replace my second for loop with the following code:
int j=0
...
for (i=0; i<n; i++)
{
if (x[i] < 0)
{
count++;
continue;
};
if (i > j)
x[j] = x[i];
j++;
};
Could someone please explain why is the latter code better?

If i==j, then you're assigning an element to itself: not wrong, but a (small) waste of effort.
If you really want to improve this, avoid putting the negative values in the array in the first place.

Related

Shell Sort C language

The task was simply to write a program to sort the entered (or randomly generated) numbers using the Shell sort method. But then the teacher decided to complicate the task and said:
Create another function that will test Shell's algorithm: create many arrays from n random numbers, sort by Shell's method and display the average number of iterations for all these arrays.
Please, help and explain how to do it
This is my code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void shellsort(int v[], int n);
int main() {
srand(time(NULL));
int N;
printf("Input N: ");
scanf_s("%d", &N);
int *a = (int *)malloc(N * sizeof(int));
int i = 0;
printf("Enter masiv: ");
for (; i < N; i++) {
a[i] = rand() % 100;
printf("%d ", a[i]);
}
shellsort(a, N);
printf("\n");
printf("Result: ");
for (i = 0; i < N; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
void shellsort(int v[], int n) {
int i, j, gap, temp;
int num = 0;
for (gap = n / 2; gap > 0; gap /= 2) {
for (i = gap; i < n; i++)
for (j = i - gap; j >= 0 && v[j] > v[j + gap]; j -= gap) {
temp = v[j];
v[j] = v[j + gap];
v[j + gap] = temp;
num++;
}
}
printf("\n");
printf("Number of iterations: %d\n", num);
}
Many thanks in advance to everyone who responds;))
Alright, I will start by saying that I am not gonna do your homework and write the code for it. I'll just try to give you a starting point.
Shell sort currently doesn't compute the number of iterations, so you might declare a variable named iterations at the beginning of shellsort and increment it in the deepest loop inside shell sort, and return this variable instead of returning void.
The new function that you're about to write should be similar to what you're doing in the main for the number generation part.
Make a loop that encapsulates the loop that generates arrays for you. Because you need multiple arrays now.
Store the sum of iterations, maybe like this sum += shellsort(a);
Then the average of iterations is the sum/N, where N is the number of random arrays you want to generate.

Pointer array sorting in C has unexpected output

#include <stdio.h>
void sort(int *ptr, int n) {
int i,j,tmp;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
if (ptr[i] < ptr[j])
{
tmp=ptr[i];
ptr[i]=ptr[j];
ptr[j]=tmp;
}
}
int main() {
int i,n;
int *ptr;
printf("Nr. of elements : 5 \n");
n=5;
ptr=(int*)malloc( n * sizeof(int));
for (i=0;i<n;i++) {
scanf("%d",&ptr[i]);
}
printf("Initial array is : ");
for (i=0;i<n;i++) {
printf("%d ",ptr[i]);
}
sort(ptr,n);
printf("Sorted array is : ");
for (i=0;i<n;i++) {
printf("%d ",ptr[i]);
}
return 0;
}
This is my code. I'm trying to sort a pointer array using a function.
Whatever the (int) input, it sorts out fine.
My confusion is that i'm using
ptr[i] < ptr[j]
instead of
ptr[i] > ptr[j]
as it should normally be to sort it ascending.
Why is that?
No, your confusion is misplaced. Look at the for loops, and the relation between i and j. There are times when i < j and times when i > j, so what constitutes being "out of order" and requiring a swap?
The inner loop should start at i+1 not at '0'; that will make the relation between i and j invariant.
Given your loops go from i = 0 .. n and j = 0 .. n, there is no guarantee in your code that i < j.
There's two ways to fix this:
void sort(int *ptr, int n) {
int i,j,tmp;
for (i=0; i<n; i++) {
for (j=0; j<n; j++) {
if (i < j && ptr[i] < ptr[j]) { // Note the changed conditional
tmp=ptr[i];
ptr[i]=ptr[j];
ptr[j]=tmp;
}
}
}
}
or
void sort(int *ptr, int n) {
int i,j,tmp;
for (i=0; i<n; i++) {
for (j=i+1; j<n; j++) { // Note the changed start value
if (ptr[i] < ptr[j]) {
tmp=ptr[i];
ptr[i]=ptr[j];
ptr[j]=tmp;
}
}
}
}
As we can see, you are using bubble sort.
In bubble sort, our main intention is either transfer the heavier element to the end or lighter element to the top.
(ptr[i] < ptr[j])
what you are doing is moving the heavy elements to the end of the array, this is why whenever you are finding ptr[j](j is an inner loop variable) which is bigger than the ptr[i] (outer loop variable), you are doing a swap.

Calling a 2D array function?

I first apologize if some of you find my problem stupid and easy to solve, but I am a very beginner in "c".
My task is to create an inverse of a 3x3 matrix using different functions.
What I am trying to do now is to tell the user to input values for the 3x3 matrix and then print them. I made 2 functions which read and print the values, but I have problems with calling them since I cannot directly call an array in printf.
For now I am able to run the program, enter the values and print a wrong result which leads to a not responding program.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3 //defining the size of the matrix (3x3)
//prototyping the functions used to calculate the inverse of the matrix
void readMatrix(double a[SIZE][SIZE]);
void printMatrix(double a[SIZE][SIZE]);
main()
{
double a[SIZE][SIZE];
int i,j;
printf("Enter the values for the matrix:\n", i, j);
readMatrix(a);
printf("Your Matrix:%d\n",a[i][j]);
printMatrix(a);
return 0;
}
//function 1
//letting the user to enter a matrix
void readMatrix(double a[SIZE][SIZE]){
int i,j;
for(i = 0; i < SIZE; i++){
for(j = 0; j < SIZE; j++){
scanf("%d", &a[i][j]);
}
}
}
//function 2
//outputing the given matrix
void printMatrix(double a[SIZE][SIZE]){
int i,j;
for(i = 0; i < SIZE; i++){
for(i = 0; i < SIZE; j++){
printf("Your matrix is: %d", a[i][j]);
}
}
}
In printf and scanf, it is crucial that you pass the exact format specifier that matches the type of the pointer to the variable. If your format specifier doesn't match the supplied argument, the result is undefined behaviour.
In effect, this
scanf("%d", &a[i][j]);
Needs to be replaced with
scanf("%lf", &a[i][j]);
And the same for printf("Your matrix is: %d", a[i][j]); -> printf("Your matrix is: %lf", a[i][j]);
Also, in printMatrix, you've used the loop variable i in the inner loop twice. What you want is
for(i = 0; i < SIZE; i++){
for(j = 0; j < SIZE; j++){
printf("%lf ", a[i][j]);
printf("\n");
}
Edit: As pointed out by #cse in the comments, remove this line in main:
printf("Enter the values for the matrix:\n", i, j);
Since at this point, i, and j are not initialised, they'd contain junk.
in printMatrix, there is a infinite loop which will definitely lead your program to no responding. Should be:
for(j = 0; j < SIZE; j++){
printf("Your matrix is: %d", a[i][j]);
}
For printing the output: you will want to actually print out the entire thing rather than one value after another, correct?
printf ("matrix is:\n")
char outstr[64]; //arbitrary but plenty big enough
char * pout; //points to a point in the string
for(j = 0; j < SIZE; j++){
pout = outstr;
for(i = 0; i < SIZE; i++){
pout += sprintf (pout, "%lf," a [i][j]);
*(--pout) = 0; //end the string one char earlier (dangling ',')
printf ("[%s]\n", outstr);
}
Will print:
matrix is:
[1,2,3]
[4,5,6]
[7,8,9]
Where the numbers are of course the ones in the array.
Also unless you were intending on filling the matrix in a columnar fashion, you should switch the i and j loops on the input function. You are storing the matrix in memory transposed. (This code assumes that you are not)
There are following problems with above code:
In line printf("Your Matrix:%d\n",a[i][j]); of main() function, since variable i and j are not initialized so it contains garbage value. So don't print value at a[i][j] because it may cause of segmentation fault. OR initialize i and j with a valid value i.e. which is a valid index in array double a[][]. Also you can change line printf("Enter the values for the matrix:\n", i, j); in main() to printf("Enter the values for the matrix:\n");. Because i and j are not being used here.
In line scanf("%d", &a[i][j]); of function void readMatrix(double a[SIZE][SIZE]). Since you are reading a double primitive data type then you should use %lf formatter instead of %d. Same for line printf("Your matrix is: %d", a[i][j]) in function void printMatrix(double a[SIZE][SIZE]).
In line for(i = 0; i < SIZE; j++) of function void readMatrix(double a[SIZE][SIZE]). It should be for(j = 0; j < SIZE; j++) i.e. the variable to be used in inner loop should be j not i.
You can find working code here which is after correcting the code.

Insertion sort program, no output

This is the simplest insertion sort program.
Unfortunately, it doesn't provide an outcome:
it does prompt the user for the size of the array
and for the list of numbers, but it doesn't do
the sort. I would be grateful for your help!
/** Insertion sort **/
#include <stdio.h>
int main (void)
{
int size, array[80], i, j, element;
printf("Enter number of elements: \n");
scanf ("%d", &size);
printf("Enter %d integers\n", size);
for (i = 0; i < size; i++)
{
scanf("%d", &array[i]);
}
for (i = 0; i < size; i++)
{
element = array[i];
j = i;
while (j > 0 && array[j-1] > element)
{
array[j] = array[j-1];
array[j-1] = element;
j--;
}
}
printf ("Sorted list in ascending order:\n");
for (i = 0; i < size; i++)
printf ("%d", array[i]);
return 0;
}
This is one of those confusing moments :)
I have forgotten that there is a '\n' character
in the second printf, after which the user is
prompted for the list. Therefore, I've kept typing
in numbers in one row, without hitting ENTER; of course,
the program considered that as one number, only one integer
not the list ))) Thank you everyone for replying.
Sorry for this.

strange behaviour when printing a float and then an Array

I try to print out two arrays with the following function using XCode 6.1.1:
for (int j=0; j<4; j++) {
for (int k=0; k<4; k++) {
printf("%2d ", Lattice[0][j+N*k]);
}
printf(" ");
for (int k=0; k<4; k++) {
printf("%2d ", Lattice[1][j+N*k]);
}
printf("\n");
}
printf("\n");
Everything works fine when calling the function,
as long as I don't print out a float before.
When printing an int, there's no problem. So it's a
little strange, right?
I'm initializing the array like this:
int **Lattice = (int**)malloc(2*sizeof(int*));
if (Lattice == NULL) return NULL;
for (int i=0; i<2; i++){
Lattice[i] = (int *)malloc(2*sizeof(int));
if (Lattice[i] == NULL) {
for (int n=0; n<i; n++)
free(Lattice[n]);
free(Lattice);
return NULL;
}
else{
for (int j=0; j<N; j++) {
for (int k=0; k<M; k++) {
Lattice[i][j+N*k] = 0;
}
}
}
}
return Lattice;
Too bad, I can't upload an image of the output.
The matrices should show only zeros, but with the float
there will be big numbers in some entries which i can't explain.
I'm grateful for any hints.
Thank you.
So your code has some pretty serious problems.
Lattice[0] and Lattice[1] need to have dimensions 4x4 for your printing block of code to make any sense. Incidentally this means N and M need to equal 4 as well or you need to change your printing for loop conditions to j < N and k < M respectively.
Your malloc needs to allocate space for that as well, so: Lattice[i] = (int *)malloc(N * M * sizeof(int));
This should cause your loops to work correctly, but you do not have floats anywhere in your code. You cannot use printf to print an int as a float. The value will not be promoted. It will simply be treated as a float.

Resources