No Output - The program doesn't give any output - arrays

I am learning data structures. I tried to write a function rotate(arr[], d, n) that rotates arr[] of size n by d elements.
By rotate I mean shifting the elements in an array.
The program doesn't give any error, rather it hangs a bit but it doesn't run.
Here's the code: -
#include <stdio.h>
int rotate(int arr[], int d, int n, int dir)
{
int temp, i;
while (d)
{
if (dir)
{
// for left shift
// First element will always get replaced in a rotation.
temp = arr[0];
for (i = 0; i < n - 1; i++)
// for left shifting the second element next to its original position.
arr[i] = arr[i + 1];
// Putting the temp value in the last position.
arr[n - 1] = temp;
}
else
{
// for right shift
// Last element will always get replaced in a rotation.
temp = arr[n - 1];
for (i = n - 1; i > 0; i--)
// for right shifting the second last element to the last position.
arr[i] = arr[i - 1];
// Putting the temp value in the first position
arr[0] = temp;
}
d--;
}
// Print the shifted array
for (i = 0; i < n; i++)
{
printf("%d, ", arr[i]);
}
}
The program only runs when I don't take inputs from the user.
int main()
{
int n;
int arr[n];
int dir;
int d;
printf("Enter the size of the array: \n");
scanf("%d", &n);
printf("Enter the elements of the array: \n");
for (int i = 1; i <= n; i++)
{
printf("Enter element %d", i);
scanf("%d", &arr[i]);
}
printf("Enter the position: \n");
scanf("%d", &d);
printf("Enter the direction: \n");
// 0: Right Direction and 1: Left Direction
scanf("%d", &dir);
// Before shifting the array
for (int i = 1; i <= n; i++)
{
printf("%d, ", arr[i]);
}
// After shifting the array
rotate(arr, d, n, dir);
return 0;
}

You might want to do int arr[n] after scanf("%d", &n); because n is not initialized when you do int arr[n]. Also array indexing in C starts from 0 so for (int i = 1; i <= n; i++) will be for (int i = 0; i < n; i++).

This is not a proper answer, so do not accept it as the correct answer. It is just a possible implementation for educational purposes.
Here is a way to rotate the array so that each element is moved only once (except that the first element of a "group" is moved via a temporary variable).
The rotation amount is specified as an integer with positive values rotating right and negative values rotating left. It converts this amount into a number in the range 0 to n-1 which is the index of the element that will be copied to element 0. It then divides the array into one or more interleaved groups of the same size such that successive elements in each group are separated by the rotation amount in a circular fashion, and rotates the elements within each group. (The number of groups is the greatest common divisor of n and the rotation amount, and the number of elements in each group is the total number of elements divided by the number of groups.)
#include <limits.h>
#include <stddef.h>
static size_t rotate_modulus(int d, size_t n);
static size_t gcd_size(size_t a, size_t b);
/* Rotate arr[] of length n right by d, or left by -d. */
void rotate(int arr[], int d, size_t n)
{
size_t md = rotate_modulus(d, n); /* Get offset in range 0 to n-1. */
if (md)
{
/* Rotation needed. */
/* Divide into interleaved groups and rotate each group. */
size_t num_groups = gcd_size(n, md);
size_t group_size = n / num_groups;
size_t group;
for (group = 0; group < num_groups; group++)
{
size_t a = group; /* Index of first element in group. */
size_t i;
/* Rotate elements in group. */
int temp = arr[a]; /* Get first element. */
for (i = 0; i < group_size - 1; i++)
{
/* Get index of next element in group. */
size_t b = (a + md);
if (a >= n - md)
{
b -= n; /* Index wraps around. */
}
arr[a] = arr[b]; /* Move an element. */
a = b; /* Advance to next index. */
}
arr[a] = temp; /* Move first element to last element. */
}
}
}
/*
* Get modulus for rotation of n elements.
*
* d is the amount to rotate right; negative d rotates left by -d.
*
* For zero n, the return value is 0.
*
* For non-zero n, the return value is n - s, where s is d plus an
* integer multiple of n such that s is in the range 1 to n, and the
* return value is in the range 0 to n - 1.
*/
static size_t rotate_modulus(int d, size_t n)
{
size_t md;
if (n < 2)
{
/* No rotation needed if n < 2. */
md = 0;
}
else if (d >= 0)
{
/* Non-negative d will rotate right. */
md = d % n;
if (md)
{
md = n - md;
}
}
else
{
/* Negative d will rotate left. */
/* -d would overflow if d == INT_MIN && INT_MIN == -INT_MAX - 1. */
int fix_overflow = (d < -INT_MAX);
md = -(d + fix_overflow) % n;
if (fix_overflow)
{
if (++md == n)
{
md = 0;
}
}
}
return md;
}
/*
* If both a and b are non-zero, return the greatest common divisor of a and b.
* Otherwise, return 0.
*/
static size_t gcd_size(size_t a, size_t b)
{
if (b == 0)
{
a = 0;
}
else
{
do
{
size_t t = b;
b = a % b;
a = t;
}
while (b);
}
return a;
}

Related

transforming max-heap into min-heap with heapfy

I'm trying to heapfy a max-heap i've got into a min-heap. For some reason i'm not getting the result i expect.
i've built my max-heap and the array contents of it are showing as expected:
60 50 30 20 40 10
When trying heapfy the above array and transform it into a min-heap, the desired result is:
10 20 30 60 50 40
However, the result i'm getting is:
10 20 60 50 40 30
here are my functions:
struct _heap
{
int max; //array max
int pos; //current position
int* priority; //array gets initialized after.
};
typedef struct _heap heap_t;
void heapify_min(heap_t* h, int father)
{
int smallest = father;
int left = 2 * father + 1;
int right = 2 * father + 2;
if (left < h->pos && h->priority[left] < h->priority[smallest) {
smallest = left;
}
if (dir < h->pos && h->priority[right] < h->priority[smallest])
smallest = right;
if (smallest != father) {
swap(father,smallest,h->priority);
heapify_min(h,left);
}
}
void swap(int a, int b, int *v)
{
int f = v[a];
v[a] = v[b];
v[b] = f;
}
void build_heap(heap_t* h)
{
int n = h->pos;
int i2 = (n/2) -1;
int i;
for (i = i2;i>=0;i--) {
heapify_min(h,i);
}
}
Any insights would be really helpful.
Check your code against my (below is working code for min_heap).
There are 3 problems :
In heapify_min function when you calling function recursively you should use variable smallest not left.
operators of comparing values in MIN HEAP should be > (greater) instead of < (smaller)
Function build_heap is correct but that should be just very first rearrange of array. And after that first rearrange of array (first creation of max heap) you should swap first and last element in array. After that initial swap you continue with heapify function but every further creation of max heap, swapping values in sub-trees (during recursive calling) and swaping first element with last element is done in cycle until there is only one node left.
Here is code :
void heapify(int arr[], int n, int i)
{
int smallest = i;
int l = 2 * i + 1;
int r = 2 * i + 2;
// If left child is larger than root
if (l < n && arr[l] > arr[smallest])
smallest = l;
// If right child is larger than largest so far
if (r < n && arr[r] > arr[smallest])
smallest = r;
// If largest is not root
if (smallest != i) {
//swap
int backUp = arr[i];
arr[i] = arr[smallest];
arr[smallest] = backUp;
// Recursively call on heapify function
heapify(arr, n, smallest);
}
}
void heapSort(int arr[], int n)
{
// Build heap (rearrange array)
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// One by one extract an element from heap
for (int i = n - 1; i > 0; i--) {
// Swap root node with last node in array (WARNING: last node don't have to be
necessarily smallest one)
int backUp = arr[0];
arr[0] = arr[i];
arr[i] = backUp;
// call max heapify on the reduced heap
heapify(arr, i, 0);
}
}
/* A utility function to print array of size n */
void printArray(int arr[], int n)
{
for (int i = 0; i < n; ++i)
printf("%d ", arr[i]);
printf("\n");
}

Code on finding non-dominated points not working properly

I am a beginner at programming (and it is not my subject of discipline) and this is my first question here, apologies if I'm not posting it it properly.
I am trying a problem (in C) in which one has to define a structure for a point, take inputs of points from a file to a dynamic array, in which the first line contains the number of points, and the remaining lines contain the coordinates of the points with spaces in between. Then I have to write a function to determine the points which are non-dominated, definitions given :
• A point P1 = ( x1 , y1 ) is dominated by a point P2 = ( x2 , y2 ) if
y2 > y1 and x2 > x1
• A point is non-dominated in a set of points, if no point dominates
it in that set
And another function to determine and print the level of dominance of each point stored in the array formed. I need to print all non-dominated points, and then print level of dominance of all the points.
This is the code that I have written:
#include <stdio.h>
#include <stdlib.h>
#define MAX 20
#define TRUE 1
#define FALSE 0
typedef struct Coordinates{
float xcord;
float ycord;
}POINT;
//globally declaring dynamic array of points
POINT *Array_of_Points;
//globally declaring dynamic array of non-dominated points
POINT *Non_dominated;
//declaring some functions
int dominance(int n);
int Read_File(char filename[]);
void Xmerge(int head, int middle, int tail);
void XmergeSort(int head, int tail);
void level_of_dominance(int a);
int main(){
char Arr[MAX];
int n, i, d;
printf("Enter file name...");
scanf("%s", Arr);
n = Read_File(Arr);
if(!Read_File(Arr)){ //if error occurs
printf("Terminating program with exit code -1\n");
return -1; //terminate program with return value -1
}
//finds non-dominated points and prints them
d = dominance(n);
printf("The non dominated points are:\n");
for(i = 0; i < d; i++){
printf("(%f, %f)", Non_dominated[i].xcord, Non_dominated[i].ycord);
}
//print all points with levels of dominance
level_of_dominance(n);
printf("End of program... Terminating with exit code 0\n");
free(Array_of_Points);
free(Non_dominated);
return 0;
}
//function reads file in required manner
int Read_File(char filename[]){
int n; //to store number of points present in file
int count = 0;
float x, y;
FILE *fptr = fopen(filename, "r"); //opening given file in readable format
if(!fptr) //file handling if pointer returns null
{
printf("The file %s can't be opened.\n", filename);
return FALSE;
}
fscanf(fptr, "%d", &n); //reading first line consisting of number of points
Array_of_Points = (POINT*)malloc(n * sizeof(POINT)); //allocating memory for npoints
//reading points from file and storing them in globally created dynamic array
while((count < n) && (fscanf(fptr, "%f", &x) == TRUE && fscanf(fptr, "%f", &y) == TRUE)){
Array_of_Points[count].xcord = x;
Array_of_Points[count].ycord = y;
++count;
}
return n; //returns number of points
}
int dominance(int n){ //returns number of non-dominated points
/*METHOD TO FIND DOMINANCE:
* First, arranging points in array by sorting, say, x co-ordinates in DESCENDING ORDER...
* using merge sort algorithm for the same
* The first point in this sorted array is automatically a non dominated point,
* as no other point has x coordinate greater than it
* Then, traverse sorted array and keep track of largest y value, initializing first one to max
* While traversing, the point with y value grater than y max is also non dominated,
* and contributes to new y max and so on...
**/
int foo = 0; //keeps track of number of non-dominated points found so far, initialized to zero
int i = 0;
XmergeSort(0, n);
int ymax = Array_of_Points[0].ycord;
//add first element of the array to Non_dominated array and increase foo count
Non_dominated = (POINT*)malloc(sizeof(POINT));
Non_dominated[0] = Array_of_Points[0];
++foo;
for(; foo < n; foo++){
if(Array_of_Points[foo].ycord > ymax){
++i;
Non_dominated = (POINT*)realloc(Non_dominated, (i + 1) * sizeof(POINT));
Non_dominated[i] = Array_of_Points[foo];
}
}
//all non dominated points stored in array
return i;
}
void level_of_dominance(int a){ //returns number of points dominating a point
int i, j, flag = 0;
for(i = a - 1; i >= 0; i--){
for(j = i; j >= 0; j--){
if((Array_of_Points[i].xcord <= Array_of_Points[j].xcord)&&(Array_of_Points[i].ycord <= Array_of_Points[j].ycord)){
++flag;
}
}
printf("(%f, %f) is dominated by %d points.\n", Array_of_Points[i].xcord, Array_of_Points[i].ycord, flag);
flag = 0; //resetting number of points for next point
}
}
void XmergeSort(int head, int tail){
int mid;
if(head < tail){
mid = (head +tail)/2;
XmergeSort(head, mid);
XmergeSort(mid + 1, tail);
Xmerge(head, mid, tail);
}
}
//function to merge 2 halves of array
void Xmerge(int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
/* create temp arrays */
POINT *T1, *T2;
T1 = (POINT*)malloc(n1 * sizeof(POINT));
T2 = (POINT*)malloc(n2 * sizeof(POINT));
/* Copy data to temp arrays L[] and R[] */
for (i = 0; i < n1; i++)
T1[i] = Array_of_Points[l + i];
for (j = 0; j < n2; j++)
T2[j] = Array_of_Points[m + 1+ j];
/* Merge the temp arrays back into arr[l..r]*/
i = 0;
j = 0;
k = l;
while (i < n1 && j < n2)
{
Array_of_Points[k] = ((T1[i].xcord <= T2[j].xcord)?T1[i]:T2[j]);
((T1[i].xcord <= T2[j].xcord)?i++:j++);
k++;
}
/* Copy the remaining elements of L[], if there are any */
while (i < n1)
{
Array_of_Points[k] = T1[i];
i++;
k++;
}
/* Copy the remaining elements of R[], if there are any */
while (j < n2)
{
Array_of_Points[k] = T2[j];
j++;
k++;
}
}
While running this code on online gdb, I am getting a segmentation fault, like this:
Reading symbols from a.out...done.
/usr/share/gdb/gdbinit: No such file or directory.
(gdb) run
Starting program: /home/a.out
Enter file name...inp.dat
Testing... no. of non dominated points = 4
The non dominated points are:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400b82 in level_of_dominance (a=5) at main.c:107
107 if((Array_of_Points[i].xcord <= Array_of_Points[j].xcord)&&(Ar
ray_of_Points[i].ycord <= Array_of_Points[j].ycord)){
(gdb)
The coordinates of non-dominated points aren't being printed here either.
I'm sorry if what I'm asking is stupid, but I hope someone can help me understand what went wrong.
Thanks in advance.
P.S Please let me know if I should edit my question.
EDIT: I had made a bad mistake in line 105 of the code, as pointed out by #JGroven where in place of j--, I had written j++. I have corrected the same above, but my code isn't doing what it should. This is what the debugger is showing:
Reading symbols from a.out...done.
/usr/share/gdb/gdbinit: No such file or directory.
(gdb) run
Starting program: /home/a.out
Enter file name...inp.dat
The non dominated points are:
(0.000000, 0.000000)(2.500000, 7.200000)(4.700000, 5.000000)(5.600000, 9.500000)(9
.000000, 5.900000) is dominated by 0 points.
(5.600000, 9.500000) is dominated by 0 points.
(4.700000, 5.000000) is dominated by 0 points.
(2.500000, 7.200000) is dominated by 0 points.
(0.000000, 0.000000) is dominated by 0 points.
End of program... Terminating with exit code 0
*** Error in `/home/a.out': free(): invalid next size (fast): 0x00000000006034c0 *
**
Program received signal SIGABRT, Aborted.
0x00007ffff7a47c37 in __GI_raise (sig=sig#entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or
directory. (gdb)
EDIT 2: As further pointed out by #Hitokiri,j will become -1 if initialized to i - 1, hence I have changed that to i. And also changed the type of the function to find level of dominance into void.
I figured out my mistake with the help of a friend. The dominance function wasn't completely correct, I have made changes there. And there is something not working properly with the merge sort function I have written, which I shall try to figure out shortly. In the meantime I have replaced it with insertion sort. I am posting my corrected code below.
Thanks to everyone for your help.
#include <stdio.h>
#include <stdlib.h>
#define MAX 20
#define TRUE 1
#define FALSE 0
//segmentation fault...
typedef struct Coordinates{
float xcord;
float ycord;
}POINT;
//globally declaring dynamic array of points
POINT *Array_of_Points;
//globally declaring dynamic array of non-dominated points
POINT *Non_dominated;
//declaring some functions
int dominance(int n);
int Read_File(char filename[]);
/*void Xmerge(int head, int middle, int tail);
void XmergeSort(int);*/
void XInsertion(int n);
int level_of_dominance(int a);
int main(){
char Arr[MAX];
int n, i, d;
printf("Enter file name...");
scanf("%s", Arr);
n = Read_File(Arr);
if(!Read_File(Arr)){ //if error occurs
printf("Terminating program with exit code -1\n");
return -1; //terminate program with return value -1
}
//finds non-dominated points and prints them
d = dominance(n);
printf("The non dominated points are:\n");
for(i = 0; i < d; i++){
printf("(%f, %f)", Non_dominated[i].xcord, Non_dominated[i].ycord);
}
printf("\n");
//print all points with levels of dominance
level_of_dominance(n);
printf("End of program... Terminating with exit code 0\n");
free(Array_of_Points);
free(Non_dominated);
return 0;
}
//function reads file in required manner
int Read_File(char filename[]){
int n; //to store number of points present in file
int count = 0;
float x, y;
FILE *fptr = fopen(filename, "r"); //opening given file in readable format
if(!fptr) //file handling if pointer returns null
{
printf("The file %s can't be opened.\n", filename);
return FALSE;
}
fscanf(fptr, "%d", &n); //reading first line consisting of number of points
Array_of_Points = (POINT*)malloc(n * sizeof(POINT)); //allocating memory to store data of n points
//reading points from file and storing them in globally created dynamic array
while((count < n) && (fscanf(fptr, "%f", &x) == TRUE && fscanf(fptr, "%f", &y) == TRUE)){
Array_of_Points[count].xcord = x;
Array_of_Points[count].ycord = y;
++count;
}
return n; //returns number of points
}
int dominance(int n){ //returns number of non-dominated points
/*METHOD TO FIND DOMINANCE:
* First, arranging points in array by sorting, say, x co-ordinates in DESCENDING ORDER...
* using merge sort algorithm for the same
* The first point in this sorted array is automatically a non dominated point,
* as no other point has x coordinate greater than it
* Then, traverse sorted array and keep track of largest y value, initializing first one to max
* While traversing, the point with y value grater than y max is also non dominated,
* and contributes to new y max and so on...
**/
int foo = 0; //keeps track of number of non-dominated points found so far, initialized to zero
int i;
XInsertion(n);
int ymax = Array_of_Points[0].ycord;
//add first element of the array to Non_dominated array and increase foo count
Non_dominated = (POINT*)malloc(sizeof(POINT));
Non_dominated[0] = Array_of_Points[0];
++foo;
for(i=1 ; i < n; i++){ //note change
if(Array_of_Points[i].ycord > ymax){
ymax=Array_of_Points[i].ycord; /*changes made*/
Non_dominated = (POINT*)realloc(Non_dominated, (foo+1) * sizeof(POINT));
Non_dominated[foo] = Array_of_Points[i];
foo++;
}
}
//all non dominated points stored in array
return foo;
}
int level_of_dominance(int a){ //returns number of points dominating a point
int i, j, flag = 0;
for(i = a - 1; i >= 0; i--){
for(j = i - 1; j >= 0; j--){
if((Array_of_Points[i].xcord <= Array_of_Points[j].xcord)&&(Array_of_Points[i].ycord <= Array_of_Points[j].ycord)){
++flag;
}
}
printf("(%f, %f) is dominated by %d points.\n", Array_of_Points[i].xcord, Array_of_Points[i].ycord, flag);
flag = 0; //resetting number of points for next point
}
}
/*
void XmergeSort(int head, int tail){
int mid;
if(head < tail){
mid = (head +tail)/2;
XmergeSort(head, mid);
XmergeSort(mid + 1, tail);
Xmerge(head, mid, tail);
}
}
//function to merge 2 halves of array
void Xmerge(int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
// create temp arrays
POINT *T1, *T2;
T1 = (POINT*)malloc(n1 * sizeof(POINT));
T2 = (POINT*)malloc(n2 * sizeof(POINT));
// Copy data to temp arrays L[] and R[]
for (i = 0; i < n1; i++)
T1[i] = Array_of_Points[l + i];
for (j = 0; j < n2; j++)
T2[j] = Array_of_Points[m + 1+ j];
// Merge the temp arrays back into arr[l..r]
i = 0;
j = 0;
k = l;
while (i < n1 && j < n2)
{
Array_of_Points[k] = ((T1[i].xcord <= T2[j].xcord)?T1[i]:T2[j]);
((T1[i].xcord <= T2[j].xcord)?i++:j++);
k++;
}
// Copy the remaining elements of L[], if there are any
while (i < n1)
{
Array_of_Points[k] = T1[i];
i++;
k++;
}
// Copy the remaining elements of R[], if there are any
while (j < n2)
{
Array_of_Points[k] = T2[j];
j++;
k++;
}
}*/
void XInsertion(int n)
{
int i,j;
POINT a;
//Applying insertion-sort on x co-ordinates to have them arranged in decreasing order
for(i=0;i<n;i++)
{
j=i-1;
a=Array_of_Points[i];
while((Array_of_Points[j].xcord<=a.xcord)&&(j>=0))
{
if(Array_of_Points[j].xcord==a.xcord && Array_of_Points[j].ycord>a.ycord)
break;//in case of tie, arrange in decreasing order
else
{
Array_of_Points[j+1]=Array_of_Points[j];
j--;
}
}
Array_of_Points[j+1]=a;
}
}
And here is the output:
Enter file name...inp.dat
The non dominated points are:
(12.600000, 2.300000)(9.000000, 5.900000)(5.600000, 9.500000)
(2.500000, 7.200000) is dominated by 1 points.
(4.700000, 5.000000) is dominated by 2 points.
(5.600000, 9.500000) is dominated by 0 points.
(9.000000, 5.900000) is dominated by 0 points.
(12.600000, 2.300000) is dominated by 0 points.
End of program... Terminating with exit code 0
Any suggestions and tips to improve my program and techniques for debugging are most welcome.

Complexity to find if there is a missing element in an array

I am trying to write a function (in C) that checks if an array has all the elements (between 0 and its "size-1")
For example, if the array's size is 3, it should have {0, 1, 2 } in any order.
The question is: what is the most efficient complexity to do this without an extra array?
The complexity of my attempt, showed below, is (average of nlogn + n).
edit: sorry for the miss understanding, any whole number can be an input, which means checking size wont work --> {0, 0, 3}
int check_missing_element(int *a, int n)
{
int i = 0;
quicksort(a, 0, n - 1);
for (i = 0; i < n; i++)
{
if (a[i] != i)
return 0;
}
return 1;
}
Walk the array using the value [0...n-1] of the element as the next element to visit.
As leaving each element, set its value to n. Any visited element with an n has already been visited and so is a failure - unless we have indexed ourselves. Any element with a value outside [0...n-1] is a failure.
After 'n' visits we are done. O(n).
Sort not needed. This does consume the array.
Here is an implementation of the cycle-chasing algorithm sketched in chux’ answer, along with a test program.
/* Return 1 iff each integer in 0...n-1 appears exactly once in a[0]...a[n-1].
Return 0 otherwise.
*/
int check_missing_element(int *a, int n)
{
// Reject elements that are out of bounds.
for (int i = 0; i < n; ++i)
if (a[i] < 0 || n <= a[i])
return 0;
// Define a value to mark already seen values with.
static const int AlreadySeen = -1;
// Work through the array.
for (int i = 0; i < n; ++i)
// If we already examined this element, ignore it.
if (a[i] != AlreadySeen)
{
/* Follow the cycle defined by x -> a[x]. If we encounter an
already seen element before returning to i, report rejection.
Otherwise, mark each encountered element seen.
*/
for (int j = a[i]; j != i;)
{
int next = a[j];
if (next == AlreadySeen)
return 0;
a[j] = AlreadySeen;
j = next;
}
}
// Every element has been seen once and only once. Report acceptance.
return 1;
}
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Define a comparator for sorting int values in ascending order.
static int Comparator(const void *a, const void *b)
{
int A = * (const int *) a;
int B = * (const int *) b;
return
A < B ? -1 :
A == B ? 0 :
+1;
}
// Provide a reference routine for testing check_missing_elements.
static int check_missing_elementReference(int *a, int n)
{
/* Sort the elements. Iff the array contains each value exactly once,
this results in an array containing 0, 1, 2, 3,... n-1.
*/
qsort(a, n, sizeof *a, Comparator);
// Test the sorted array.
for (int i = 0; i < n; ++i)
if (a[i] != i)
return 0;
return 1;
}
#define ArrayLimit 7
#define NumberOf(a) (sizeof (a) / sizeof *(a))
/* Define a structure used to iterator through test values.
The indices in the Index array will each run from -x to n, inclusive,
where x is the number of special values (defined below) and n is the array
size. The indices will be incremented lexicographically (odometer style).
For the indices from -x to -1, the associated value will be one of the
special values. For the indices from 0 to n, the associated value will
equal the index. Note that n is outside the bounds of array values that
pass the test. It is included in testing so that rejections based on it
are tested.
*/
typedef struct
{
int Index [ArrayLimit];
int Values[ArrayLimit];
} Iterator;
// Define special values to include in testing.
static const int SpecialValues[] = { INT_MIN, -1, INT_MAX };
/* Define the number of special values as an int, not a size_t, because we use
its negation and so need a signed type.
*/
#define NumberOfSpecialValues ((int) NumberOf(SpecialValues))
// Initialize an iterator.
static void InitializeIterator(Iterator *Iterator, int n)
{
for (int i = 0; i < n; ++i)
{
Iterator->Index [i] = -NumberOfSpecialValues;
Iterator->Values[i] = SpecialValues[0];
}
}
/* Increment an iterator. Return 0 if we are done (all fields rolled over,
bringing the iterator back to the initial state) and 1 otherwise.
*/
static int Increment(Iterator *Iterator, int n)
{
// Start at the rightmost field.
int j =n-1;
while (0 <= j)
{
// If this field has room to increase, increment it.
if (Iterator->Index[j] < n)
{
++Iterator->Index[j];
/* Set the associated value to either a special value or the
index value, as described above.
*/
Iterator->Values[j] =
Iterator->Index[j] < 0
? SpecialValues[Iterator->Index[j] + NumberOfSpecialValues]
: Iterator->Index[j];
// There is no carry into the next field, so we are done.
return 1;
}
/* This field rolls over and resets to its initial value. Then we
carry into the next field.
*/
Iterator->Index [j] = -NumberOfSpecialValues;
Iterator->Values[j] = SpecialValues[0];
--j;
}
// All fields rolled over, so we are done.
return 0;
}
// Print an array.
static void PrintArray(int *a, int n)
{
printf("[");
if (0 < n)
printf("%d", a[0]);
for (int i = 1; i < n; ++i)
printf(", %d", a[i]);
printf("]");
}
int main(void)
{
// Test each array size up to the limit.
for (int n = 1; n <= ArrayLimit; ++n)
{
// Iterator through all array values.
Iterator i;
for (InitializeIterator(&i, n); Increment(&i, n);)
{
/* Since the routines destroy the array, copy the array. Then
execute the routine and record the return value.
*/
int Buffer[ArrayLimit];
// Reference routine first.
memcpy(Buffer, i.Values, n * sizeof *Buffer);
int expected = check_missing_elementReference(Buffer, n);
// Subject routine.
memcpy(Buffer, i.Values, n * sizeof *Buffer);
int observed = check_missing_element (Buffer, n);
// Test for a bug.
if (expected != observed)
{
printf("Failure:\n");
printf("\tArray = "); PrintArray(i.Values, n); printf("\n");
printf("\tExpected %d but observed %d.\n", expected, observed);
exit(EXIT_FAILURE);
}
}
printf("Array length %d: Passed.\n", n);
}
}

Is there a algorithm to print all arrengments of subsequences of an array?

I am working with combinatorics and I would like to know if there is an algorithm that prints all arrangments of subsequences of a given array. That is, if I give to this algorithm the sequence "ABCDEF" it will print :
A,
B,
C,
D,
E,
F,
AB,
AC,
AD,
AE,
AF,
BC,
BD,
BE,
BF,
CD,
CE,
CF,
DE,
DF,
EF,
ABC,
ABD,
ABE,
ABF,
ACD,
ACE,
ACF,
ADE,
ADF,
AEF,
BCD,
BCE,
BCF,
BDE,
BDF,
BEF,
CDE,
CDF,
CEF,
DEF,
ABCD,
ABCE,
ABCF,
ABDE,
ABDF,
ABEF,
ACDE,
ACDF,
ACEF,
ADEF,
BCDE,
BCDF,
BCEF,
BDEF,
CDEF,
ABCDE,
ABCDF,
ABCEF,
ABDEF,
ACDEF,
BCDEF,
ABCDEF,
or for a more simple case, if i give it 1234, it will print:
1,2,3,4,12,13,14,23,24,34,123,124,134,234,1234.
As you can see it is not an arbitrary permutation it is only the permutation of the last members of a subsequence in a way it still reains a subsequence.
I have tried to make a function in c that does this but i got really confused, my idea would be to make a int L that keeps the size of the subsequence,and another tree integers one that keeps the head of the subsequence, one that marks the separation from the head and one that slides trought the given number of characters, but it gets too confused too quickly.
Can anyone help me with this ?
my code is:
int Stringsize( char m[] ){
int k;
for(k=0;;k++){
if( m[k] == '\0') break;
}
return (k-1);
}
void StringOrdM(char m[]){
int q,r,s,k;
for(k=0;k<=Stringsize(m);k++)
for(q=0;q<=Stringsize(m);q++)
for(s=q;s<=Stringsize(m);s++ )
printf("%c",m[q]);
for(r=q+1; r<=Stringsize(m) && (r-q+1)<= k ;r++ )
printf("%c", m[r] );
}
And for ABCD it prints A,A,A,A,B,B,B,C,C,D,AA,AB,AC,AD,BC,BD,CC,CD,DD,... so it is not right because it keeps repeating the A 4 times the B three times and so on, when it should have been A,B,C,D,AB,AC,AD,BC,BD,CD,...
As I said in my comment above, one solution is simple: count in binary up to (1<<n)-1.
So if you have four items, count up to 15, with each bit pattern being a selection of the elements. You'll get 0001, 0010, 0011, 0100, 0101, 0110, 0111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111. Each bit is a true/false value as to whether to include that element of the array.
#include <stdio.h>
int main(void) {
////////////////////////////////////////////////////////////////////////
int A[] = { 1, 2, 3, 4, 5 };
////////////////////////////////////////////////////////////////////////
size_t len = sizeof A / sizeof A[0]; // Array length (in elements)
size_t elbp = (1<<len) - 1; // Element selection bit pattern
size_t i, j; // Iterators
// Cycle through all the bit patterns
for (i = 1; i<=elbp; i++) {
// For each bit pattern, print out the 'checked' elements
for (j = 0; j < len; j++) {
if (i & (1<<j)) printf("%d ", A[j]);
}
printf("\n");
}
return 0;
}
If you want the elements sorted shortest to longest, you could always store these results in a string array (using sprintf()) and then sort (using a stable sorting algorithm!) by string length.
I mentioned in a comment above that if you didn't want to use a bit pattern to find all permutations, and sort the results according to whatever criteria you'd like, you could also use a recursive algorithm.
I suspect this is a homework assignment, and you only asked for an algorithm, so I left some of the key code as an exercise for you to finish. However, the algorithm itself is complete (the key parts are just described in comments, rather than functional code being inserted).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printpermutations(const int *A, const size_t n, const char *pfix, const size_t rd);
int main(void) {
/////////////////////////////////////////////////////////////////////
int A[] = { 1, 2, 3, 4, 5 };
/////////////////////////////////////////////////////////////////////
size_t n = sizeof A / sizeof A[0]; // Array length (in elements)
size_t i; // Iterator
for (i = 1; i <= n; i++) {
printpermutations(A, n, "", i);
}
return 0;
}
// Recursive function to print permutations of a given length rd,
// using a prefix set in pfix.
// Arguments:
// int *A The integer array we're finding permutations in
// size_t n The size of the integer array
// char *pfix Computed output in higher levels of recursion,
// which will be prepended when we plunge to our
// intended recursive depth
// size_t rd Remaining depth to plunge in recursion
void printpermutations(const int *A, const size_t n, const char *pfix, const size_t rd) {
size_t i;
char newpfix[strlen(pfix)+22]; // 20 digits in 64-bit unsigned int
// plus a space, plus '\0'
if (n < rd) return; // Don't bother if we don't have enough
// elements to do a permutation
if (rd == 1) {
for (i = 0; i < n; i++) {
// YOUR CODE HERE
// Use printf() to print out:
// A string, consisting of the prefix we were passed
// Followed immediately by A[i] and a newline
}
}
else {
strcpy(newpfix, pfix);
for (i = 1; i <= n; i++) {
// YOUR CODE HERE
// Use sprintf() to put A[i-1] and a space into the new prefix string
// at an offset of strlen(pfix).
// Then, call printpermutations() starting with the ith offset into A[],
// with a size of n-i, using the new prefix, with a remaining
// recursion depth one less than the one we were called with
}
}
}
Depending on torstenvl's answer I did this code and It works perfectly.
If there is any problem let me know.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char str[] = "1234";
size_t len = strlen(str); // Array length (in elements)
char *A = malloc(sizeof(char) * len);
strcpy(A,str);
size_t elbp = (1<<len) - 1; // Element selection bit pattern
size_t i, j; // Iterators
int a = 0, b = 0, n = 0;
char **arr = malloc(sizeof(char*) * (10000)); //allocating memory
if (A[0] >= 'A' && A[0] <= 'Z') //If the string given is "ABCD...." transfer 'A' to '1' ; 'C' to '3' ...etc
for(int i = 0; i < len; i++)
A[i] = A[i] - 'A' + '1';
// Cycle through all the bit patterns
for (i = 1; i<=elbp; i++)
{
arr[b] = malloc(sizeof(char) * len);
// For each bit pattern, store in arr[b] the 'checked' elements
for (j = 0, a = 0; j < len; j++)
if (i & (1<<j))
arr[b][a++] = A[j];
b++;
}
int *num = calloc(sizeof(int) ,10000);
for (i = 0; i < b; i++)
num[i] = strtol(arr[i], NULL, 10); //convert char to int
for (i = 0; i < b; i++) //sort array numbers from smallest to largest
for (a = 0; a < i; a++)
if (num[i] < num[a])
{
n = num[i];
num[i] = num[a];
num[a] = n;
}
char *result = calloc(sizeof(char),10000);
for (i = 0, a = 0; i<b; i++)
a += sprintf(&result[a], "%d,", num[i]); //convert int to char and store it in result[a]
result[a - 1] = '\0'; //remove the last ','
len = strlen(result);
if (str[0] >= 'A' && str[0] <= 'Z') //if the string given is "ABCD..." transfer '1' to 'A' ; '12' to 'AB' ; '13' to 'AC'.....etc
for (i = 0; i < len; i++)
if(result[i] != ',')
result[i] = 'A' + (result[i] - '1') ;
///test
printf("%s",result);
return 0;
}
the output for "1234":
1,2,3,4,12,13,14,23,24,34,123,124,134,234,1234
the output for "123456789":
1,2,3,4,5,6,7,8,9,12,13,14,15,16,17,18,19,23,24,25,26,27,28,29,34,35,36,37,38,39,45,46,47,48,49,56,57,58,59,67,68,69,78,79,89,123,124,125,126,127,128,129,134,135,136,137,138,139,145,146,147,148,149,156,157,158,159,167,168,169,178,179,189,234,235,236,237,238,239,245,246,247,248,249,256,257,258,259,267,268,269,278,279,289,345,346,347,348,349,356,357,358,359,367,368,369,378,379,389,456,457,458,459,467,468,469,478,479,489,567,568,569,578,579,589,678,679,689,789,1234,1235,1236,1237,1238,1239,1245,1246,1247,1248,1249,1256,1257,1258,1259,1267,1268,1269,1278,1279,1289,1345,1346,1347,1348,1349,1356,1357,1358,1359,1367,1368,1369,1378,1379,1389,1456,1457,1458,1459,1467,1468,1469,1478,1479,1489,1567,1568,1569,1578,1579,1589,1678,1679,1689,1789,2345,2346,2347,2348,2349,2356,2357,2358,2359,2367,2368,2369,2378,2379,2389,2456,2457,2458,2459,2467,2468,2469,2478,2479,2489,2567,2568,2569,2578,2579,2589,2678,2679,2689,2789,3456,3457,3458,3459,3467,3468,3469,3478,3479,3489,3567,3568,3569,3578,3579,3589,3678,3679,3689,3789,4567,4568,4569,4578,4579,4589,4678,4679,4689,4789,5678,5679,5689,5789,6789,12345,12346,12347,12348,12349,12356,12357,12358,12359,12367,12368,12369,12378,12379,12389,12456,12457,12458,12459,12467,12468,12469,12478,12479,12489,12567,12568,12569,12578,12579,12589,12678,12679,12689,12789,13456,13457,13458,13459,13467,13468,13469,13478,13479,13489,13567,13568,13569,13578,13579,13589,13678,13679,13689,13789,14567,14568,14569,14578,14579,14589,14678,14679,14689,14789,15678,15679,15689,15789,16789,23456,23457,23458,23459,23467,23468,23469,23478,23479,23489,23567,23568,23569,23578,23579,23589,23678,23679,23689,23789,24567,24568,24569,24578,24579,24589,24678,24679,24689,24789,25678,25679,25689,25789,26789,34567,34568,34569,34578,34579,34589,34678,34679,34689,34789,35678,35679,35689,35789,36789,45678,45679,45689,45789,46789,56789,123456,123457,123458,123459,123467,123468,123469,123478,123479,123489,123567,123568,123569,123578,123579,123589,123678,123679,123689,123789,124567,124568,124569,124578,124579,124589,124678,124679,124689,124789,125678,125679,125689,125789,126789,134567,134568,134569,134578,134579,134589,134678,134679,134689,134789,135678,135679,135689,135789,136789,145678,145679,145689,145789,146789,156789,234567,234568,234569,234578,234579,234589,234678,234679,234689,234789,235678,235679,235689,235789,236789,245678,245679,245689,245789,246789,256789,345678,345679,345689,345789,346789,356789,456789,1234567,1234568,1234569,1234578,1234579,1234589,1234678,1234679,1234689,1234789,1235678,1235679,1235689,1235789,1236789,1245678,1245679,1245689,1245789,1246789,1256789,1345678,1345679,1345689,1345789,1346789,1356789,1456789,2345678,2345679,2345689,2345789,2346789,2356789,2456789,3456789,12345678,12345679,12345689,12345789,12346789,12356789,12456789,13456789,23456789,123456789
the output for "ABCDEF":
A,B,C,D,E,F,AB,AC,AD,AE,AF,BC,BD,BE,BF,CD,CE,CF,DE,DF,EF,ABC,ABD,ABE,ABF,ACD,ACE,ACF,ADE,ADF,AEF,BCD,BCE,BCF,BDE,BDF,BEF,CDE,CDF,CEF,DEF,ABCD,ABCE,ABCF,ABDE,ABDF,ABEF,ACDE,ACDF,ACEF,ADEF,BCDE,BCDF,BCEF,BDEF,CDEF,ABCDE,ABCDF,ABCEF,ABDEF,ACDEF,BCDEF,ABCDEF
Combinations, or k-combinations, are the unordered sets of k elements chosen from a set of size n.
Source: http://www.martinbroadhurst.com/combinations.html
This is the code:
unsigned int next_combination(unsigned int *ar, size_t n, unsigned int k)
{
unsigned int finished = 0;
unsigned int changed = 0;
unsigned int i;
if (k > 0) {
for (i = k - 1; !finished && !changed; i--) {
if (ar[i] < (n - 1) - (k - 1) + i) {
/* Increment this element */
ar[i]++;
if (i < k - 1) {
/* Turn the elements after it into a linear sequence */
unsigned int j;
for (j = i + 1; j < k; j++) {
ar[j] = ar[j - 1] + 1;
}
}
changed = 1;
}
finished = i == 0;
}
if (!changed) {
/* Reset to first combination */
for (i = 0; i < k; i++) {
ar[i] = i;
}
}
}
return changed;
}

My code Catalan number in C is not working ( using recurrence formula )

I am trying to insert all Catalan number in array, but my code is not working.
Description: Insert the elements in the Catalan sequence in the array given initialized only for C[0].
Inputs: address of array
n: next position to be filled;
top: maximum number of entries to be computed.
Output:
int: number of elements in the array.
Side effects: update the elements of the array.
Code:
#include <stdio.h>
#define MAX 6
int CatSeq (int CatArray[], int n, int top){
int c;
if (top == 1) CatArray[n]= 1;
else{
for ( c = 0; c <= MAX; c++){
CatArray[n] = 2 * (2*top - 1) * CatSeq(CatArray, n, top-1) / (top+1);
n++;
}
}
return n;
}
void PrintSeq(int Seq[], int top){
int i;
for ( i = 1; i < MAX; i++)
printf("%d \n", Seq[i]);
}
int main(){
int c = 0, n = 0 ;
int CatArray[MAX];
c = CatSeq(CatArray, n, MAX);
PrintSeq(CatArray, c);
return 0;
}
Array out of index error:
for ( c = 0 ; c <= MAX;c++){
^
check loop
Correct is:
for ( n = 0 ; n < MAX; n++){
it should be n < MAX, since n could be passed in as non-zero to the function.
CatArray[n] = 2 * (2*top - 1) * CatSeq(CatArray, n, top-1) / (top+1);
^
here n is non-zero
no need of c variable.

Resources