Rotating array anti-clockwise, unexpected debug output in one step - c

I'm using the simplest approach to rotate array anti-clockwise i.e by storing elements from index=0 to index=number of rotating positions required, in a temporary array and finally inserting these elements int he end of another array. Here's the code:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *a, *temp, i, j=0, n,np,*b;
printf("Enter no. of elements in arr:\n");
scanf("%d",&n);
a=(int*) malloc(n*sizeof(int));//Primary array
b=(int*) malloc(n*sizeof(int));//Final array that would be printed in the end
printf("Enter elements:\n");
for(i=0;i<n;i++)
scanf("%d",&a[i]);
printf("Enter positions to be rotated anti-clockwise:\n");
scanf("%d",&np);
temp=(int*) malloc(np*sizeof(int));//storing elements left of index=0
for(i=0;i<np;i++,j++)
{
//printf("hi\n");
temp[j]=a[i];
printf("temp[%d]=%d\n",j,temp[j]);
}
j=0;
printf("After rotating:\n");
for(i=n-1;i>=0;i--)
{
printf("i=%d ",i);
b[i-np]=a[i];
printf("b[%d]=%d\n",i-np,b[i]); /*Here is 1 unexpected thing happening, the program is not picking up correct value of array a at index i.*/
}
for(i=np-1;i<n;i++,j++)
b[i]=temp[j];//storing temp elements in final array
printf("Finally matrix is\n");
for(i=0;i<n;i++)
printf("%d\n",b[i]);
getch();
return 0;
}

Either you try to rotate the array elements one direction or the other, the procedure is always the same: Take a copy of the extremum element you ar going to move to the other extreme. Then, copy the next element (from the element you saved to the other side) into the hole you have opened. Finally, cover the hole with the saved element.
typedef int ARRAY_ELEMENT;
ARRAY_ELEMENT the_array[N_ELEMENTS];
/* to put the first element at the end */
ARRAY_ELEMENT saved_element = the_array[0];
for (int i = 1; i < N_ELEMENTS; i++) the_array[i-1] = the_array[i];
the_array[N_ELEMENTS-1] = saved_element;
/* to put the last element at the beginning */
ARRAY_ELEMENT saved_element = the_array[N_ELEMENTS-1];
for (int i = N_ELEMENTS-1; i > 0; i--) the_array[i] = the_array[i-1];
the_array[0] = saved_element;
You can do this also by swapping the first element with the second, the second to the third, etc... up to the next to last and the last. You'll reach the same result, but with a lot of more assignments (three assignments per round, instead of one)
if you want only to rotate part of an array, design a routine that considers the pointer to the first element and the number of these as parameters... and then apply it to the array part you want to rotate.
void rotate_upwards(ARRAY_ELEMENT *a, size_t n) /* a[0] -> a[1], a[1] -> a[2] ... */
{
ARRAY_ELEMENT saved = a[n-1];
int i;
for (i = n-1; i > 0; i--) a[i] = a[i-1];
a[i] = saved;
} /* rotate_upwards */
void rotate_downwards(ARRAY_ELEMENT *a, size_t n) /* a[0] <- a[1], ... */
{
ARRAY_ELEMENT saved = a[0];
int i;
for (i = 0; i < n-1; i++) a[i] = a[i+1];
a[i] = saved;
} /* rotate_downwards */
if you want then to rotate 5 elements of array[100] at position 33, you can use
rotate_downwards(array + 33, 5);
and you'll rotate only a slice of an array.

If I understood correctly in the incriminated print you are printing the rotated array.
The problem is with the element you are printing:
printf("b[%d]=%d\n",i-np,b[i]);
You in fact are printing b[i], I think that there you want to print either a[i] or b[i-np].

This loop where you remark "unexpected thing" is in error
for(i=n-1;i>=0;i--)
{
printf("i=%d ",i);
b[i-np]=a[i]; // <--- error here
printf("b[%d]=%d\n",i-np,b[i]); /*Here is 1 unexpected thing happening, the program is not picking up correct value of array a at index i.*/
}
You are indexing b[i-np] which will break b when i < np, which it will be.
I can't suggest a solution, since I don't understand what the question means by "rotating an array anti-clockwise".

Related

I'm trying to merge two sorted (int)arrays using pointers and for some reason it stores the addresses

void interclas(int *ptr,int *vec, int *c, int n) {
int i,j,tmp;
tmp=0;
for (i=0;i++;i<n)
for (j=0;i++;j<n)
{
if (vec[j]<=ptr[i])
c[tmp]=vec[j];
else
c[tmp]=ptr[i];
tmp++;
}
}
int main() {
int i,n;
int *ptr,*vec,*c;
printf("Nr. of elements of initial arrays : 5 \n");
n=5;
vec=(int*)malloc( n * sizeof(int));
ptr=(int*)malloc( n * sizeof(int));
c=(int*)malloc( 2 * n * sizeof(int));
for (i=0;i<n;i++) {
scanf("%d",&ptr[i]);
}
for (i=0;i<n;i++) {
scanf("%d",&vec[i]);
}
printf("\n");
printf("Initial arrays are : ");
for (i=0;i<n;i++) {
printf("%d ",ptr[i]);
}
printf("\n");
for (i=0;i<n;i++) {
printf("%d ",vec[i]);
}
interclas(ptr,vec,&c,n);
printf("Merged array is : ");
for (i=0;i<10;i++) {
printf("%d ",c[i]);
}
return 0;
}
So I'm trying to merge two sorted arrays into one new one using pointers with the function 'interclas'. I tried using the same method to sort an array with a pointer in a function and it worked just fine. Now as you can see, it stores the adress of the variable rather than the variable itself.
If I run this, it stores the adresses of the arrays. How can I fix this? (I'm still new to pointers)
In your method's body, change:
for (i=0;i++;i<n)
for (j=0;i++;j<n)
to this:
for (i=0; i<n; i++)
for (j=0; j<n; j++)
and then change the call to your method, from this:
interclas(ptr, vec, &c, n);
to this:
interclas(ptr, vec, c, n);
since the prototype expects a pointer to an int, for the third parameter.
The logic of your method is also flawed, try to put some printfs (e.g. printf("here i = %d, j = %d, ptr[i] = %d, vec[j] = %d, tmp = %d\n", i, j, ptr[i], vec[j], tmp);) to see what values your variables have at its iteration - you only get the first two elements of the first array to be merged!
If you think about it, what you'd like to do is to go through the first element of array ptr and vec, and store the minimum of this two. If now that min was of array ptr, you'd like the next element of ptr to be taken into account, otherwise the next element of vec.
Take a pencil and a paper and sketch that algorithm - you'll see that it goes out nicely, but some leftover elements might be left behind, and not get inserted in the output array.
Driven from that observation, after traversing both the arrays and comparing elements, we will loop over the first array, if needed, to collect elements that were not visited. Similarly for the second array.
Coding that thought gives something like this:
void interclas(int *ptr,int *vec, int *c, int n) {
int i = 0, j = 0, tmp = 0;
// Traverse both arrays simultaneously,
// and choose the min of the two current elements.
// Increase the counter of the array who had
// the min current element.
// Increase the counter for the output array in
// any case.
while(i < n && j < n)
{
if(ptr[i] < vec[j])
{
c[tmp++] = ptr[i++];
}
else
{
c[tmp++] = vec[j++];
}
}
// Store remaining elements of first array
while (i < n)
c[tmp++] = ptr[i++];
// Store remaining elements of second array
while (j < n)
c[tmp++] = vec[j++];
}
Not the source of your problem, but Do I cast the result of malloc? No.

Binary search not returning the position

this code is used to create an array filled with 10 random integers. It sorts the array and then inputs the array into a binary search function. I do not get the position of where my search key is positioned.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int binary_search(int array[], int search, int strt, int ending)
{
int middle;
middle = (strt + ending)/2;//splitting the array in half to compare the search key
if (search > array[middle]){binary_search(array, search, middle + 1, ending);}
else if(search == array[middle])
{
printf("Your search key is indicated in %d position the array Ferrari\n", middle + 1);
return middle;
}
else{binary_search(array, search, strt, middle -1);}
return -1;
}
int main()
{
srand(time(NULL));//random number seed generator
int Ferrari[10];
int size = 10;
int selection;
int temporary = 0;//I'm using this variable to store
//the value returned from linear_search()
int start = 0;
int end;
int i;
//this is to generate a random number between 0 and 101
for(int i=0; i<10; i++) {Ferrari[i] = rand() % 100 + 1;}
//printing the initial array
printf("\nThe array Ferrari consists of -> ");
for(int i=0; i<10; i++){printf("%d, ", Ferrari[i]);}
//--------------------------SORTING--------------------------------------------
for(int f = 0; f < (size - 1); f++)
{
for(int kk = 0; kk < (size - 1 - f); kk++)
{
if(Ferrari[kk] > Ferrari[kk +1])
{
int Te_mP;
Te_mP = Ferrari[kk + 1];
Ferrari[kk+1] = Ferrari[kk];
Ferrari[kk] = Te_mP;
}
}
}
//----------------------------------------------------------------------------
//printing the array after it has been sorted
printf("\n");
printf("\nThe sorted array Ferrari consists of -> ");
for(int i=0; i<10; i++){printf("%d, ", Ferrari[i]);}
start = 0;
end = i -1;
//this will be used to implement the searching algorithm
printf("\n\n");
printf("Please enter a number to test if it is included in the array or not\n");
scanf("%d", &selection);
temporary = binary_search(Ferrari, selection, start, end);
return 0;
}
I keep getting the answer that the search key is positioned in ``0 of array Ferrari. How do I resolve this?
Please let me know what I'm doing wrong over here. Much appreciated.
Look at this line
end = i - 1;
Where is i initialized?
In your loop you have
for(int i=0........
Note by giving int i=0 it means you are creating a new variable i within the for block. So this doesn't alter your original i variable declared at the top. Try using end = size - 1 or it's a best practice to define a constant for this purpose.
#define ARR_SIZE 10
in loop
for(i=0; i<ARR_SIZE;i++)
Then initialize end = ARR_SIZE -1;
And one more thing in your binary_search function is that you don't handle the case when the key is not present in the array.
Something like
if(end==start && array[end] != search)
return -1;
This checks when the search space has only one element and that is not your search element, it means it doesn't exist so we return -1.
Hope this helps
The problem is occurring because you are using uninitialised variable i here:
end = i -1;
Note that the scope of variable i declared in loop init clause is different from the scope of variable i declared in function block.
for(int i=0; i<10; i++){
^^^^^^^
// The scope of i declared in loop init clause is limited to the loop.
To fix the problem, you can use the i declared at function block scope as the loop variable, like this
for(i=0; i<10; i++){
Now, after the loop finishes, the variable i will hold its last value until it's value explicitly modify. But using i to identify the size of array down the code may cause several problems as it is not tightly coupled with the size of array and i may be get modified by other part of code. So, it is not the right idea to use i to identify the size of array.
Since, you are having a variable size which hold the size of array Ferrari, you can do:
end = size - 1;
No need to have another variable to keep the track of size of array. The problem with this is that you have to keep updating the size whenever you change the array size. An alternative of this would be to use a macro to define the array size.
The most appropriate way to set the end of array would be:
end = (sizeof(Ferrari) / sizeof(Ferrari[0])) - 1;

How to pass a 2D array to function with a row offset like M*i in C?

for(int i=0; i < n; ++i){
//Find the leading element in a+M*i
if(!find_leading_element((a+M*i),n-i,m,&rowLead,&columnLead)){
return;
}
//Get the dividable from a[rowLEad][columnLead]
divide = (double)1/a[rowLead][columnLead];
printf("The divide from current matrix is %d\n\n",divide);
//Swap the current row = i with rowLead in matrix a+M*i
swap_rows((a+M*i),n-i,m,i,rowLead);
}
I am working on a small school project for reducing matrices but having some troubles passing the 2D array with an offset.
I need the find_leading_element to get a 2D array and return via the pointers the row and column of the leading element in that matrix.
Therefore find_leading_element returns the row and col relative to the matrix it got, and it is okay I will handle it later on. Now the issue is with passing the 2D array with a row offset.
So with each iteration I will pass the matrix but with one row less. Since I can't change the declaration for find_leading_element, I need to pass the function with double a[][M], does it mean it is passed by value?
bool find_leading_element(double a[][M], int n, int m, int * row, int * column) {
printf("In Find Leader got the matrix\n");
print_matrix((double (*)[M])a,n,m);
for(int i=0; i < m; ++i){
for(int j=0; j < n; ++j){
if(*(&a[0][0]+j*M+i) != 0){
*row = j;
*column = i;
return true;
}
}
}
return false;
}
double a[N][M];
printf("Enter matrix:\n");
if (!read_matrix((double (*)[M]) a, n, m)) {
printf("Invalid matrix!\n");
return ERROR;
}
What is the best way to do it? The way I do it here it only receives on the second iteration one row.
Beware pointer arithmetics is not raw addresses arithmetics.
As a is a 2D array declared as double a[N][M]; it will decay to a pointer to a row. That means that the address of the i-th row is a+i and not a+M*i.
The latter is used when you simulate a 2D array with a 1D one: int aa[N*M];. Here aa will decay to an int pointer and the beginning of the i-th row would be at aa+M*i.
The call should be:
//Find the leading element in a+M*i
if(!find_leading_element((a+i),n-i,m,&rowLead,&columnLead)){
return;
}

function to perform bubble sort in C providing unstable results

I am participating in Harvard's opencourse ware and attempting the homework questions. I wrote (or tried to) write a program in C to sort an array using bubble sort implementation. After I finished it, I tested it with an array of size 5, then 6 then 3 etc. All worked. then, I tried to test it with an array of size 11, and then that's when it started bugging out. The program was written to stop getting numbers for the array after it hits the array size entered by the user. But, when I tested it with array size 11 it would continuously try to get more values from the user, past the size declared. It did that to me consistently for a couple days, then the third day I tried to initialize the array size variable to 0, then all of a sudden it would continue to have the same issues with an array size of 4 or more. I un-did the initialization and it continues to do the same thing for an array size of over 4. I cant figure out why the program would work for some array sizes and not others. I used main to get the array size and values from the keyboard, then I passed it to a function I wrote called sort. Note that this is not homework or anything I need to get credit, It is solely for learning. Any comments will be very much appreciated. Thanks.
/****************************************************************************
* helpers.c
*
* Computer Science 50
* Problem Set 3
*
* Helper functions for Problem Set 3.
***************************************************************************/
#include <cs50.h>
#include <stdio.h>
#include "helpers.h"
void
sort(int values[], int n);
int main(){
printf("Please enter the size of the array \n");
int num = GetInt();
int mystack[num];
for (int z=0; z < num; z++){
mystack[z] = GetInt();
}
sort(mystack, num);
}
/*
* Sorts array of n values.
*/
void
sort(int values[], int n)
{
// this is a bubble sort implementation
bool swapped = false; // initialize variable to check if swap was made
for (int i=0; i < (n-1);){ // loops through all array values
if (values[i + 1] > values [i]){ // checks the neighbor to see if it's bigger
i++; // if bigger do nothing except to move to the next value in the array
}
else{ // if neighbor is not bigger then out of order and needs sorting
int temp = values[i]; // store current array value in temp variable for swapping purposes
values[i] = values[i+1]; //swap with neighbor
values[i+1] = temp; // swap neighbor to current array value
swapped = true; // keep track that swap was made
i++;
}
// if we are at the end of array and swap was made then go back to beginning
// and start process again.
if((i == (n-1) && (swapped == true))){
i = 0;
swapped = false;
}
// if we are at the end and swap was not made then array must be in order so print it
if((i == (n-1) && (swapped == false))){
for (int y =0; y < n; y++){
printf("%d", values[y]);
}
// exit program
break;
}
} // end for
// return;
}
You can easily use 2 nested for loops :
int i, j, temp ;
for ( i = 0 ; i < n - 1 ; i++ )
{
for ( j = 0 ; j <= n - 2 - i ; j++ )
{
if ( arr[j] > arr[j + 1] )
{
temp = arr[j] ;
arr[j] = arr[j + 1] ;
arr[j + 1] = temp ;
}
}
}
also you should now it's a c++ code not a c, because c doesn't have something like :
int mystack[num];
and you should enter a number when you're creating an array and you can't use a variable (like "int num" in your code). This is in C, but in C++ you're doing right.
The first thing to do when debugging a problem like this is ensure that the computer is seeing the data you think it should be seeing. You do that by printing out the data as it is entered. You're having trouble with the inputs; print out what the computer is seeing:
static void dump_array(FILE *fp, const char *tag, const int *array, int size)
{
fprintf(fp, "Array %s (%d items)\n", tag, size);
for (int i = 0; i < size; i++)
fprintf(fp, " %d: %d\n", i, array[i]);
}
int main(void)
{
printf("Please enter the size of the array \n");
int num = GetInt();
printf("num = %d\n", num);
int mystack[num];
for (int z = 0; z < num; z++)
{
mystack[z] = GetInt();
printf("%d: %d\n", z, mystack[z]);
}
dump_array(stdout, "Before", mystack, num);
sort(mystack, num);
dump_array(stdout, "After", mystack, num);
}
This will give you direct indications of what is being entered as it is entered, which will probably help you recognize what is going wrong. Printing out inputs is a very basic debugging technique.
Also, stylistically, having a function that should be called sort_array_and_print() suggests that you do not have the correct division of labour; the sort code should sort, and a separate function (like the dump_array() function I showed) should be used for printing an array.
As it turns out the reason why it was doing this is because when comparing an array's neighbor to itself as in:
if (values[i + 1] > values [i])
The fact that I was just checking that it is greater than, without checking if it is '=' then it was causing it to behave undesirably. So if the array is for example [1, 1, 5, 2, 6, 8] then by 1 being next to a 1, my program did not account for this behavior and acted the way it did.

Recursive Sort Function

I've written a program to recursively sort an array.
However, I get the following error on line 11: syntax error before ']' token.
Here is the code:
//This program recursively sorts an array
#include<stdio.h>
void rec_sort(int values[], int n);
main()
{
int vals[4];
vals[0] = 37; vals[1] = 48; vals[2] = 56; vals[3] = 63;
printf("this array sorted: %x\n", rec_sort(vals[], 4));
system("Pause");
return 0;
}
void rec_sort(int values[], int n) {
//Base case
if (n<2) return;
int maxIndex=0;
int i;
//Find max item in array in indexes 0 through n-1
for(i=1; i<n;i++) {
if(values[i] > values[maxIndex])
maxIndex=i;
}
//Swap this element with one stored in n-1
//Set temp to n-1, set n-1 in array to max, set max to temp
int temp = values[n-1]; //Store temp as last element in array
values[n-1] = values[maxIndex]; //Store last element as max value in array
values[maxIndex] = temp; //temp will keep on changing, as array is sorted
//Recursively sort the array values of length n-1
sort(values, n-1);
}
It looks like you're trying print out the whole array, which C won't do in one call to printf. Instead, you need a loop to iterate through the array and print out each number individually:
for (i=0; i<4; i++)
printf("%x\n", vals[i]);
Since rec_sort isn't returning the array, you also need to invoke it separately from the call the printf, so you'd get something like:
// sort the data:
rec_sort(vals, 4);
// print the sorted values:
for (i=0; i<4; i++)
printf("%x\n", vals[i]);
Just remove the [] on line 11. But this is a naive answer to your question, and won't get you far. There are other problems - the most obvious is the idea of printf(..., rec_sort(...)...);
Considering rec_sort has void return type, how do you expect printf() to understand what to do? I am not sure what you want either, but this should be at least a start for you.
printf("this array sorted: %x\n", rec_sort(vals[], 4));
but rec_sort() is void. Doesn't return anything
void rec_sort(int values[], int n)
Also, declare your main as int main()
The problem is in this:
rec_sort(vals[], 4)
What exactly do you want to do there? The [] is an index operation, so either you need to put a number in there, or you leave them out completely (if you want to talk about the whole array).
The first thing you should do is remove the square brackets:
printf("this array sorted: %x\n", rec_sort(vals, 4));
Second, note that rec_sort returns void, so you cant use the return value
you need
int i; // at the top of the main
// ...
rec_sort(vals, 4);
printf("this array sorted: ");
for(i = 0; i < 4; ++i) printf("%x ", vals[i]);
printf("\n");
Third: you need to call rec_sort again
Fourth: what are you tryin to do with the system statement?

Resources