please explain shellsort code in C - c

This code is written in ANSI C by Ritchie..... I have used a comment in this code that my doubt. Also i have learnt shell sort from youtube and have understood how it actually works but this code is very confusing specially these loop....why have they used gap= n/2....what is gap? and what are these loop doing here.....Plz :(
void shellsort(int v[], int n)
{
int gap, i, j, temp;
for(gap= n/2; gap >0; gap /=2) // What is this 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;
}
}

what edition of the book are you reading from? i think there are a number of programming errors in the example code all the way untill 3rd edition.
gap refers to the int you declared above the for loop. like gap, i, j & temp are also integers. this means they hold a integer numeric value (e.g, 1,2, 12, 586 etc).
a /= b is a division assignment so its literal meaning is a = a / b.
you might also be wondering what v & n are?
int v[] refers to an int array, so any value used inside the [ ] is the index of that array, e.g v[0], v[1], v[2], v[n]...
Since v & n are declared as parameters of the shellsort function, it means that when you call the function, it will need to be passed an int array value, as well as an int value. without these values the function cannot operate properly
if you have the C book, everything you need to know about C will be in that book :)

Related

Can an array in C be indexed by a character?

void shifttable(char p[]) {
int i, j, m;
m = strlen(p);
for (i = 0; i < MAX; i++)
t[i] = m;
for (j = 0; j < m - 1; j++)
t[p[j]] = m - 1 - j;
}
I think, t[p[j]]=m-1-j; part, is indexed using a character.
Can someone explain me how its actually working?
The array indexing operator is treated as *(arr + index).
When one operand of the binary + operator is a pointer, the other operand must be an integral type.
char is an integral type.
Hence,
t[p[j]] = m-1-j;
is a legal statement.
The character will be converted to equivalent ascii value and it acts as an index to an array. Below piece of code gives you an example,
void main()
{
int a[10];
a['\t'] = 10;
printf("%d\n",a[9]);
}
Output: 10
Here ascii value of tab is 9 so a[9] will be 10. Please refer https://www.asciitable.com/ for decimal and hex equivalent of character.
Hope it helps you.
p[j] returns the ascii code of j-th character in p[], which is used later as index in t (the ascii code is extended to int by the compiler, see integer promotions).
char is an integral type. It can be used as an index value for the [] operator. Note however that t['0'] is not the same element as t[0]. The value of '0' depends on the encoding used on the platform. Most environments use ASCII for the source and execution character sets, where '0' has the value 48.
Indexing through character values is useful for many algorithms, especially searching and word matching. Typical implementations of the functions in <ctype.h> use arrays of 257 entries (or sometimes 384 entries for safety) where the function argument is used as an index.
Yet there is a major problem in using char values an index variables: the char type can be signed or unsigned by default, so the range of its values can encompass negative values. In the code fragment, if t is an array or a pointer to the beginning of an array, any character in p with a negative value will cause an access outside the boundaries of the array, which has undefined behavior.
It is advisable to raise the warning level so the compiler diagnoses such uses that are well hidden potential bugs. Use gcc -Wall or clang -Weverything.
To avoid this potential problem, the code should be modified this way:
#define MAX 256
int t[MAX];
void shifttable(char p[]) {
int i, j, m;
m = strlen(p);
for (i = 0; i < MAX; i++)
t[i] = m;
for (j = 0; j < m - 1; j++)
t[(unsigned char)p[j]] = m - 1 - j;
}
Note also that i, j, m and the t array should have type size_t to handle strings longer than INT_MAX.

Example 1-7 from The C Programming Language(version 2)

I am having trouble understanding the example 1.7 given in The C Programming Language. The main purpose of this example is to illustrate the use of functions in C. The book describes the following program as such, "Since C has no exponentiation operator like ** of Fortran, let us illustrate the mechanics of function definition by writing a function power(m,n) to raise an integer m to a positive power n. That is, the value of power(2,5) is 32. This function is not a practical exponentiation routine since it handles only positive powers of small integers, but it's good enough for illustration."
This is the block of C code that follows:
#include <stdio.h>
int power(int m, int n); /*function prototype */
int main() {
/* test power function */
int i;
for(i = 0; i < 10;++i)
printf("%d %d %d\n",i,power(2,i),power(-3,i));
return 0;
}
/* power: raise base to the nth power;n >=0 */
int power(int base,int n) {
int i , p;
p = 1;
for(i = 1;i <= n;++i)
p = p * base;
return p;
}
I understand everything up to the power function's code block. What is confusing me is that for loop. I am still learning C(obviously, i'm in the first chapter) but I come from JavaScript. So when I see this for loop I expect the i to need to be 'bound' to something for it to be of us in iteration(similar to the first for loop in the example). But the power function returns p after p = p * base;. It's not returning anything to do with i. So to me, I think, what is the purpose of this for loop? I notice that if I comment out the for loop and remove the integer i then the numbers printed out do not increment except for the numbers within the previous for loop. To me, I expect the int n would need to increment. Not the i.
It appears to me that within the for loop that n is only being used as comparison to i. Is the purpose of the for loop in the power function only to execute p = p * base if i <= n is true? That can't be true because if that was then it would better be server with just an if statement and wouldn't need a ++i to increment.
What am I missing here?
The for-loop in the power function repeatedly multiplies (and updates) p by base. It does this n times -- i is the counter. If an if-statement were used, then you'd only get up to one multiplication.

Arguments to Partition function for Quicksort

So I've been attempting to write a stack-based quicksort function, which calls a partition function. The header for partition() is as follows:
int partition(void **A, int n, void *pivot, int (cmp)(void *, void *));
where A is the array, n is the size of the array and pivot is the value of the pivot (not the index).
My current call to partition is:
partition(&A[low_int], high_int + 1, A[low_int+(high_int-low_int)/2], cmp)
Above, my values for low and high are the classic 'l' and 'h' used in iterative quicksort, where l begins as the lowest index (and h the highest). These values then change as the function continues.
I'll post my partition function below:
int
partition(void **A, int n, void *pivot, int (cmp)(void *, void *)) {
int k;
int i = 0;
for (int j = 0; j <= n-2; j++) {
if (cmp(A[j], pivot) <= 0) {
i++;
swap(A, i, j);
}
}
swap(A, i+1, n-1);
k = i + 2;
return k; //k is the first value after the pivot in partitioned A
}
My problem is deciding on the inputs for my call to partition(). For the first argument, I've chose &A[low_int], as I'm not using a "left" as one of my inputs and therefore am trying to create a pointer to essentially start my array later. The third argument if for pivot, where I've been trying to select an element within that range, but both this and argument 1 have been causing my code to either return an unsorted array or run infinitely.
Could I please get some help here with what I've done wrong and how to fix it?
I've tried to include all relevant code, but please let me know if I've missed anything important or if anything I've written is unclear, or you need more info. Thank you
Consider what happens if low_int is 1000 and high_int is 2000 and the array ends at 2000. Now you give it the array B = &A[1000] and the value 2001. The value of 2001 causes it to access the element B[2001-1] = B[2000] = A[3000]. It's accessing the array out of bounds.
Shouldn't you use something like high_int - low_int + 1 for the second argument? Note: I haven't verified that your code doesn't have off-by-one errors with the argument high_int - low_int + 1 but anyway it seems to me that you should be substracting low_int from high_int.
Another option would be to give it A, low_int and high_int.

finding how many times an element has repeated in c

I've got a c study which it must print all the numbers in an array then how many times they repeated.
int lottery(int a,int b,int c,int d,int e,int f,int i,int count)
{
printf("Enter the loop count:");
scanf("%d",&d);
a=time(NULL);
srand(a);
int genel[100][100];
int hepsi[50]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49};
count=0;
for(e=0;e<=d-1;e++)
{
for(b=0;b<=5;b++)
{
genel[e][b]=(rand()%49+1);
while(i>=0 && i<=49)
{
if(genel[e][b]==hepsi[i])
{
count=count+1;
}
else{
count=count;
}
}
printf("%d->%d\t",genel[e][b],count);
}
}
}
This doesnt work obviously. the output must be something like that
1-->0 2-->3 3-->15 etc
TY for your help, cheers :)
It is important that you understand what you are doing, naming is therefore very important. Nesting loops is okay if you know what you are doing. An easier to understand approach would be:
void lottery() {
int i, j //forloop counters
int randArray[100][100]; //array for random values
srand(Time(NULL)); //set random seed based on system time
//set random values
for(i = 0; i < 100; i++) {
for(j = 0; j < 100; j++) {
randArray[i][j] = rand()%49 + 1; //sets random ranging from 1 to 49 (49 incl)
}
}
//here you can start the counting procedure, which I won't spoil but ill give some hints below
}
There are a few options, first the easy lazy approach:
use a loop over all the values, 'int number' from 1 up to 49, inside that forloop use two forloops to search through the whole array, incrementing int x everytime you encounter the value 'number'. After youve searched through the whole array, you can use printf("%d -> %d", number, x); to print the value, set x to zero and count another number.
Another approach is as u tried,
create an array with for each number a location where you can increment a counter. Loop through the whole array now using two for-loops, increment the arraylocation corresponding to the value which youve found at randArray[i][j]. Afterwards print the array with counts using another forloop.
I suggest you try to clean up your code and approach, try again and come back with problems you encounter. Good luck!
sorry if this wasn't helpful to you, I tried to spoil not too much because according to my own experience programming should be learned by making mistakes.

The difference between n++ and ++n at the end of a while loop? (ANSI C)

this is probably a dumb question but I just can't figure it out. It has to do with the differences between n++ and ++n (which I thought I understood but apparently not).
#include <stdio.h>
#include <math.h>
long algorithmA(int n);
long algorithmB(int n);
int main(){
long A, B;
A = B = 0;
int n = 1;
while(A >= B){
A = algorithmA(n);
B = algorithmB(n);
n++;
}
printf("At n = %d, Algorithm A performs in %ld seconds & "
"Algorithm B performs in %ld seconds.", n, A, B);
}
long algorithmA(int n){
return pow(n,4) * 86400 * 4;
}
long algorithmB(int n){
return pow(3,n);
}
Here you can probably tell I'm trying to see at what point Algorithm A outperforms Algorithm B. The functions and units of time were given to me in a homework problem.
Anyways, I always thought that the order of "++" would not matter at the end of a while loop. But if I put ++n instead of n++, I get the wrong answer. Can somebody explain why?
Edit: Well it WAS showing 24 with ++n and 25 with n++, but it must have been for another reason. Because I just checked now and there is no difference. Thanks for your patience and time guys, I just wish I knew what I did!
If you increment without assignment, no difference. However, in the following circumstances, there is:
int n = 1;
int x = n++; // x will be 1 and n will be 2
In this example, the statement gets executed prior to the increment.
int n = 1;
int x = ++n; // both x and n will be 2
However, in this example, increment occurs prior to the execution of the statement.
Operator precedence can help you out.
The only difference between n++ and ++n is that n++ yields the original value of n, and ++n yields the value of n after it's been incremented. Both have the side effect of modifying the value of n by incrementing it.
If the result is discarded, as it is in your code, there is no effective difference.
If your program is behaving differently depending on whether you write
n++;
or
++n;
it must be for some other reason.
In fact, when I compile and execute your program on my system, I get exactly the same output in both cases. Adding newlines to the output format, I get:
At n = 25, Algorithm A performs in 114661785600 seconds &
Algorithm B performs in 282429536481 seconds.
You haven't told us what output you're getting. Please update your question to show the output in both cases.
The prefix versions (++n) alter the variable and then pass along its value.
The postfix version (n++) pass along the current value and then alter the variable.

Resources