Recursive Sort Function - c

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?

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.

How to compare if an array is the same in reverse in C?

C language
I want to compare an array with it's reversed form and check to see if it's the same.
For example, arr1 = 5 5 8 8 5 5
Reversed arr1 = 5 5 8 8 5 5
Then output would be: Array is the same in reverse.
For some reason when I try to compare my two arrays, it ALWAYS says it is the same even if it is not.
For example : 7 8 9 is entered. The reverse is 9 8 7, which is not the same as what was entered. However, my code says it is.
How can I fix my comparison so that the results are accurate? Please advise, thank you!
I tried using goto to display results. This is my code (function):
void function(int *arr)
{
int j, c, temp, size;
size = sizeof(arr);
int old[size];
int new[size];
/*Prints original array from user input*/
printf("Input Array: ");
for(j=0; j<size; j++)
{
printf("%d ", arr[j]);
old[j] = arr[j];
}
printf("\n");
/* Reversing the array */
c = j - 1;
j = 0;
while (j < c)
{
temp = arr[j];
arr[j] = arr[c];
arr[c] = temp;
j++;
c--;
}
/* Print Reversed Array */
int i;
for(i=0; i<size; i++)
{
printf("%d ", arr[i]);
/*saved to new for possible comparison*/
new[i] = arr[i];
}
printf("\n");
/* Compare original array with reversed array */
if(temp = arr[j])
{
goto same;
} else {
goto notsame;
}
same:
printf("Array is the same in reverse\n");
return 0;
notsame:
printf("Array is not the same in reverse\n");
return 0;
}
You can't get the size of the array with sizeof. You should print out size and see what that value is giving you, it won't be the size of the array.
The reason you are always getting the "same" is that you aren't actually comparing values. You are assigning arr[j] to temp. if(temp = arr[j]) should be if(temp == arr[j]). I think you will find that it won't go to same anymore.
An easier way to solve this problem would be:
void checkReverse(int* arr, int arrSize)
{
// Loop through the array until you have hit the middle
for (int i = 0; i < (arrSize - i); i++)
{
// Check the element to the element in the same place counting from the back
if (arr[i] != arr[arrSize - i - 1])
{
// If we find any that don't match, we know it's not the same and can return
printf("Array is NOT the same in reverse.\n");
return;
}
}
// If we made it this far, they are the same
printf("Array is the same in reverse.\n");
return;
}
You need to modify your code with the following two points:
In your code, size means the number of elements in the array correct? so to calculate it correctly replace
size = sizeof(arr)/sizeof(int);
sizeof gives you the memory size occupied by the array, so for the array of three integers, it gives 3*int size. To count the elements of an array you need to use sizeof(array) and divide it with the size of the data type.
You need to traverse in the loop and compare each element of the original array and reversed array to confirm is it the same not.
So you need to replace your comparison logic with :
/* Compare original array with reversed array */
for(i=0;i < size;i++)
{
if(new[i] != old[i]){
printf("Array is not the same in reverse\n");
return;
}
}
printf("Array is the same in reverse\n");
return;
If you want to use recursion to solve this problem.
#include <stdio.h>
int compare(int *arr, int p, int q)
{
/* base case, if we are at or pass the middle point */
if (p >= q)
return 1;
if (arr[p] != arr[q]) {
return 0;
} else {
return compare(arr, p + 1, q - 1);
}
}
int main(int argc, char *argv[])
{
int arr1[] = {5, 5, 8, 8, 5, 5};
size_t array_size = sizeof(arr1) / sizeof(int);
int first = 0;
int last = array_size - 1;
if (compare(arr1, first, last)) {
printf("Array is same in reverse\n");
} else {
printf("Array is not same in reverse\n");
}
return 0;
}
Best solution to this question during an interview IMO: Use a stack:
step 1)
racecar -> push into stack -> STACK
step 2)
STACK-> pop from stack -> racecar
The input and output strings are the same, therefore the word is a palindrome.
As opposed to:
step 1) something -> push into stack -> STACK
step 2) STACK-> pop from stack -> gnihtemos
The input and output strings are NOT the same, therefore the word is NOT a palindrome.

Correctly passing an array from a function

I have some code to generate an array of size [user_input] in a function called array_generator, using size of array from scanf in main(), and then filling it with the numbers 0 to user_input (0, 1, 2, 3, if user input is 4). The array fills correctly as printf prints
`The array contains the value 1`
`The array contains the value 2`
`The array contains the value 3`, etc.
However when I pass the array to main and printf the array values I get equal statements filled with garbage numbers. I'm also 90% sure I have been passing the arrays and pointers incorrectly (new to them).
The code is below:
#include <stdio.h>
int *array_generator(int number_songs);
int main(void)
{
int input;
int *p;
int i;
int x;
printf("Enter number of songs wanted in random playlist: ");
scanf("%d", &input);
p = array_generator(input);
x = *p;
for (i = 0; i < input; i++)
{
printf("The array contains the values %d\n", x);
}
return 0;
}
int *array_generator(int n)
{
int a[n];
int *p;
int i;
for (i = 0; i < n; i++)
{
a[i] = i;
printf("The array contains the values %d\n", i);
}
return p = &a[n];
}
One simple solution is to define an array which is bigger than the largest list of songs reasonably possible. For example, since you print every entry, more than a few hundred are not reasonable. On a modern computer space is abundant. You would have a define for the max size on top of the prog, or later in some header:
#define MAX_SONGLIST_LEN 1000
The array can be global, or it can be static inside the function. Let's make it static because you want the function to return the address.
The change is minimal. Just say
static int a[MAX_SONGLIST_LEN];
You may want to change the loop and check for the max length as well:
for (i = 0; i < input && i < MAX_SONGLIST_LEN; i++)
inside array_generator() and main(). You also may want to inform your users about the maximum, and catch numbers which are too large. (You don't do any error handling of user input anyway -- what happens if the user enters a letter instead of a number? Look into the return value of scanf().)
The static array's life time is the lifetime of the program. It will be initialized to all zeroes by the way. If you want to randomly initialize it look at the rand() function.
You are correct in that you are using pointers wrong. The code below preforms the function that you want...
#include <stdio.h>
void array_generator(int n, int arr[]) {
for (int i = 0; i < n; i++) {
arr[i] = i;//array values
//printf("The array contains the values %d\n", i);
}
}
int main() {
int input;
printf("Enter number of songs wanted in random playlist: ");
scanf("%d", &input);
int array[input];//declare array with length of input
array_generator(input, array);
for(int i=0; i<sizeof(array)/sizeof(array[0]); i++) {//input could also be used at the limit to the for loop
printf("%d", array[i]);
}
printf("\n");
return 0;
}
What you are doing is you are over complicating your code. The first thing you do is you create a function and try to make it return an array. This is not necessary. All you need to do is pass a pointer to the array and all edits to the array will be made on the same scope as the array was declared on.
You also mentioned that you want to find the size of an array. This can be done with array *a of any type and sizeof(a)/sizeof(a[0]). This works by returning the number of bytes used by the array divided by the number of bytes used by the first element in the array.
One more thing that you have that you don't need is x = *p;. when you do this, you are essentially doing this x=*p=array_gen(input);
More information on pointers in C can be found here.

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

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".

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.

Resources