Sorting array of structures in C error - c

I am writing a phonebook application in C. I have an array (sort2) of structure Nodes (contacts). I am trying to sort the array by nodes->pnum (phone number); s is the number of nodes in array. For some reason, the loop creates an error after first iteration. Why?
for(i=0; i<s;i++)
{
for(j=0;j<s;j++)
{
num1= sort2[i];
num2= sort2[j];
if(num1->pnum<num2->pnum)
{
temp=sort2[j];
sort2[j]=sort2[j+1];
sort2[j+1]=temp;
printf("%s",sort2[j]->lname);
printf("%s",sort2[j+1]->lname);
}
}
}

You are accessing beyond the bounds of the array in the following lines when j is equal to s-1:
sort2[j]=sort2[j+1];
sort2[j+1]=temp;
printf("%s",sort2[j+1]->lname);
I think you meant to use:
sort2[j]=sort2[i];
sort2[i]=temp;
printf("%s",sort2[i]->lname);

In the above code when you refer to sort2[j+1] at the last iteration of the loop it would result into access to the garbage memory as array indexing starts from 0 so the last index is limit-1 i.e s-1 in this case but code will access sort[s]. Thus this would result into abnormal termination of the program in certain cases.
And starting the inner loop from the next value of outer loop counter would save some iterations of your code.
so try
for(i=0; i<s;i++)
{
for(j=(i+1);j<(s-1);j++)
{
num1= sort2[i];
num2= sort2[j];
if(num1->pnum<num2->pnum)
{
temp=sort2[j];
sort2[j]=sort2[j+1];
sort2[j+1]=temp;
printf("%s",sort2[j]->lname);
printf("%s",sort2[j+1]->lname);
}
}
}

Related

Comparing elements from two 2d-arrays in C without strcmp

I am creating a spell-checker in C. I have a dictionary array which is a 2d array. So each word in the dictionary takes a row in the 2d array. In the same way, my input array is also a 2d array. I want to check the spelling of the rows/words in my input array. I cannot use strcmp
An example of input array
['boy','girll','.','friend',' ']-can contain spaces,punctuation and words. We only care about spelling words
if a punctuation/space is compared against a word,we ignore it and move onto the next word.
example of dictionary
['boy','girl','cow'...]-all are words
My code is:
for (int a = 0; a < MAX_INPUT_SIZE + 1; a++)
{
for (int b = 0; b < MAX_DICTIONARY_WORDS; b++)
{
if(tokens[a]==dict_token[b])
{
printf("correct");
}
else
{
printf("wrong");
}
}
}
The output is all "wrong". Though 5 out of the 6 word input should be correct.
Every test returns false because the comparison you're using,
if(tokens[a]==dict_token[b])
is comparing two pointers that are never going to point at the same address, because, the tokens you are testing are in a completely separate bit of memory to the dict_token dictionary that you are comparing them with.
You need to pass the two pointers tokens[a] and dict_token[b] to a comparison function that will perform a letter-by-letter comparison, and which will return one value when it finds a difference between them, and another when it gets to the end of both without finding a difference. In other words, you need to write an implementation of strcmp.

Bubble sort concept

I just want the explanation about the condition in nested for loop.
How its processing, i am bit confused. I want the logic behind the conditions of two for loops.
#include<stdio.h>
void bubblesort(int a[25],int n);
int main()
{
int a[25],size,i;
printf("Enter the size of an array");
scanf("%d",&size);
for(i=0;i<size;i++)
{
scanf("%d",&a[i]);
}
bubblesort(a,size);
for(i=0;i<size;i++)
{
printf("%d\t",a[i]);
}
return 0;
}
void bubblesort(int a[], int n)
{
int temp,i,j;
for(i=0;i<n;i++)
{
for(j=0;j<(n-i)-1;j++)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]= temp;
}
}
}
}
Bubble sort is a commonly used algorithm for sorting an array of integers. It's called "bubble sort" since it causes the largest values to "bubble" up to the end of the array.
Bubble sort moves one index at a time up the array essentially pulling the largest value along. For example, If the array is [1,3,2] bubble sort will check the 1 and see if it is greater than the value ahead of it: 3. It isn't so the one will stay in its place. Now the 3 is the largest value the program has seen so it will compare it to the next value, the 2. Is 3 bigger? Yes! So it will switch the 3 and the 2. Now the largest value is at the end of the array so the algorithm starts at the beginning of the array again. This repeats until the entire array is sorted.
On to the specifics:
The first for-loop for(i=0;i<n;i++) loops for the same amount of times as the size of the array, i.e. if the size is 7, this loops will execute 7 times. It does this because, in the worst case scenario, every value in the array will need to change location.
The inner-most for-loop for(j=0;j<(n-i)-1;j++) first of all has j never reaching the very last array spot, even when i = 0. This is because the code inside the loop, if(a[j]>a[j+1]), is always checking one value AHEAD of the current index. So, j must never equal the last value of the index because there will be an out of bounds error.
You will also notice that the inner-more for-loop goes from 0 to n-i-1. The reason this -i is included is because every time the outer loop, if(a[j]>a[j+1])`, is executed, one value will have moved all the way up to the end of the array. So you don't need to check the very last spot in the array because it's already correct!
Summary:
Bubble sort continually moves the largest value to the end of the list. It does this by constantly checking values as it moves up the list and moving the largest value up one step at a time.
Edit: See Cool Guy's comment for a link to a great visual representation of bubble sort.

Bug While i try to compare

Actually i have a little bug with this code:
printf("Estadio Nemesio Diez\n\n");
for(i=0;i<12;i++)
{
if(ultimoAnoDiez[0]==ultimoAnoDiezOriginal[i]);
{
mes=i;
}
}
i am comparing 2 arrays, and im selecting the index[0], because that array is already sorted, but when i compile and execute the file, the program says that all the values on each array is the same, but if i print the values of each array all are diferents.
I will appreciate the help
BTW Im programmin on C
I think there can be two reasons:
First
your if condition is ending with ; (making {/* othet statement */} a block but not if block)
Second
(ultimoAnoDiez[0]==ultimoAnoDiezOriginal[i])
should be (you should be comparing individual values and not all values(i) to first value(0) only)
(ultimoAnoDiez[i]==ultimoAnoDiezOriginal[i]);
Further to check for array equality you return as soon as you find unequal values so it should be like
int mes = 12;
for(i=0;i<12;i++)
{
if(ultimoAnoDiez[i]!=ultimoAnoDiezOriginal[i])
{
mes=i;
break;
}
}
if(mes < 12){
//UNEqual
}

Inserting values into array while searching another array in C?

i'm a beginner in c, i have attempted to insert a value into an array as i scan another array for a value higher than a threshold, if a value is over the set threshold in the array being searched then insert a number into the other array...
for (i = 0; i<lines[i][1]; i++) {
if (lines[i][1] > 6500) {
array[];
}
so what i mean is, if there is a value in lines[i][1] higher than 6500, then insert number "1" into array[].
However, with previous attempts it just overwrites the array rather than stacks on top of previous values.. i have another for loop attempting to do the same thing while searching another array.
for (i = 0; i<lines[i][0]; i++) {
if (lines[i][0] > 6500) {
array[];
}
The ideal output would be something like: 1 for values higher than in lines[i][0] and 2 for values higher than in lines[i][1], "array[] = {1,1,1,2,2,2,2,1,1,1,};"
and the values are inserted into the array as arrays are being scanned.
Please help... thank you
Just start a counter to keep track of the position where you last inserted the item on the destination array. For example:
int destPosition=0;
for (i = 0; i<lines[i][0]; i++) {
if (lines[i][0] > 6500) {
array[destPosition]=1;
destPosition++;
}
}

Test for first empty value of array

Is there anyway to test for the first empty value of a 2 dimensional int array in c?
In my current program, I used 2 for loops before the main program(while loop) to set all the values of my 2 dimensional array to -9999. Then inside my main while loop, I test for the first -9999 value and set it to a value, and then use break to exit from it.
Using this I managed to do my assignment, but I'm not very satisfied, as I think there might be a better solution.
Is there one?
EDIT: Code since you asked for it.
For loop outside while loop:
for(int x=0;x<ctr-1;x++)
{
for(int y=0;y<maxtrips;y++)
{
EmployeeKilos[x][y] = -9999; // Set all the kilos to -9999 to signify emptiness.
}
}
Inside my main while loop:
for(int x=0;x<ctr-1;x++) // and set it to the log kilometers
{
if(employeenames[x].EmployeeNumber == log.Record)
{
for(int y=0;y<maxtrips;y++)
{
if(EmployeeKilos[x][y] == -9999)
{
EmployeeKilos[x][y] = log.Kilometers;
break;
}
}
}
}
All my code: http://pastebin.com/Zb60mym8
As Dave said, checking for empty values cannot be made more efficient than linear time (O(n)), but my answer focuses on a solution that can prevent having to look for it in the first place.
In general you could iterate the matrix in row-major or column-major mode.
Effectively, you can use a single index that translates to a matrix cell like so
for (size_t i=0; i<ROWS*COLS; ++i)
{
int row = i / ROWS;
int col = i % ROWS;
// work with matrix[row][col]
}
This way you could just store and remember the value of i where you last found the first empty cell, so you don't have to restart from the beginning.
If you're not actually interested in row/col addressing, you could forget about those and just use an output iterator to track your current output location.
Here's a demo using 'iterator' style (borrowing from c++ but perfectly C99)
typedef int data;
typedef data* output;
output add_next(data matrix[ROWS][COLS], output startpoint, data somevalue)
{
if (output < (matrix + ROWS*COLS))
*(output++) = somevalue;
return output;
}
Now you can just say:
add_next(matrix, 42);
add_next(matrix, 9);
NOTE the output iterator thing assumes contiguous storage and therefore cannot be used with so-called jagged arrays
HTH
You can use memset to initialise arrays to a fixed value - it's a bit more efficient and cleaner looking than iterating over the array.
Checking for your 'empty' value can't be done much faster than you are doing it, though. :)
This sounds like you should think about your datatype. Since you are already using structs. why don't you add another int for the last unassigned value so you just loop to it. something like
e.g:
struct t_EmployeeKilos{
int kilos[maxtrips];
int nlast;
} EmployeeKilos[N];
and set nlast whenever you assign a new element in kilos. This way it is O(1).
for(int x=0;x<ctr-1;x++) //
{
if(employeenames[x].EmployeeNumber == log.Record)
{
EmployeeKilos[x].kilos[EmployeeKilos[x].nlast] = log.Kilometers;
EmployeeKilos[x].nlast++;
}
}

Resources