Given an array of numbers, print the each and every range available.
For example
Array : 9, 3, 5, 7, 4, 8, 1
Output: 1, 3-5, 7-9
Note: Please execute this problem without using an additional array.
How do i proceed?
*
#include<stdio.h>
int main()
{
int a[]={9,8,8,7,6,5,14};
int n= sizeof(a) / sizeof(a[0]);
int i,j;
int temp;
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(a[i]>a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
}
*
1st i will sort in ascending order, i don't know what to do next?
P.S : I am coding this in C.
The next step is to identify sequences. Try the following loop (not fully debugged):
first= next= a[0];
for (i=1; i<n; i++) {
if (a[i] > next+1) {
if (next>first)
printf("%d-%d,", first, next);
else printf("%d,", first);
first= next= a[i];
}
else next++;
}
If you may to change the original array that is if you may to sort it then the program can look like
#include <stdlib.h>
#include <stdio.h>
int cmp( const void *lhs, const void *rhs )
{
int a = *( const int * )lhs;
int b = *( const int * )rhs;
return ( b < a ) - ( a < b );
}
int main()
{
int a[] = { 9, 8, 8, 7, 6, 5, 14 };
const size_t N = sizeof( a ) / sizeof( *a );
qsort( a, N, sizeof( int ), cmp );
/*
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
*/
int *p = a;
int *start = a, *end = a;
do
{
if ( ++p == a + N || *p != *end + 1 )
{
printf( "{ %d", *start );
start == end ? printf( " }\n" ) : printf( ", %d }\n", *end );
start = end = p;
}
else
{
end = p;
}
} while ( p != a + N );
}
The program output is
{ 5, 8 }
{ 8, 9 }
{ 14 }
I wrote a simple, readable function for you, take a look:
void printRange(int sortedArray[], int len) {
int i, current, next, printStart, printEnd, startIndex = 0;
bool print = false;
for (i = 0; i < len; i++) {
printStart = sortedArray[startIndex];
printEnd = sortedArray[i];
current = sortedArray[i];
if(i < len -1) {
next = sortedArray[i + 1];
} else
next = current;
if (next - current != 1) {
startIndex = i + 1;
print = true;
}
if (print) {
if (printStart - printEnd == 0) {
printf("%d,", printStart);
} else {
printf("%d-%d,", printStart, printEnd);
}
print = false;
}
}
}
Run live.
Note, for good understanding variable current is declared whereas current and printEnd is same. You may replace current by printEnd.
There are already some pretty good answers for this task in here but maybe the sorting part in the beginning is worth to talk a little bit more about. Especially if you need something like that in school, university or in a job interview.
The easiest sorting technique/algorithm would be something like BubbleSort which can easily be implemented with 2 for loops.
void BubbleSort (int a[], int length)
{
int i, j, temp;
for (i = 0; i < length; i++)
{
for (j = 0; j < length - i - 1; j++)
{
if (a[j + 1] < a[j])
{
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
}
Source and more information
The best way of sorting such arrays with integers (or any kind of number) is QuickSort. The algorithm is pretty advanced but if you watch a good video on Youtube or read this article you definitely know how it works.
void quick(int array[], int start, int end){
if(start < end){
int l=start+1, r=end, p = array[start];
while(l<r){
if(array[l] <= p)
l++;
else if(array[r] >= p)
r--;
else
swap(array[l],array[r]);
}
if(array[l] < p){
swap(array[l],array[start]);
l--;
}
else{
l--;
swap(array[l],array[start]);
}
quick(array, start, l);
quick(array, r, end);
}
}
Source and more information
Note: QuickSort uses a technique called recursion. If you are not familiar which that you can have a look here:
In computer science, recursion is a method of solving a problem where the solution depends on solutions to smaller instances of the same problem. Such problems can generally be solved by iteration, but this needs to identify and index the smaller instances at programming time. Recursion solves such recursive problems by using functions that call themselves from within their own code. The approach can be applied to many types of problems, and recursion is one of the central ideas of computer science.
Source and more information
Related
So currently I am trying to make a quicksort algorithm for an array of strings (to sort them alphabetically) since I can't use the qsort() function for this exercise and I also cannot allocate memory (malloc(), etc). So, I tried to do it recursively. After testing the first time it worked but as I added more text to the array, it now throws a trace trap which I don't know how to fix.
#include <stdio.h>
#include <string.h>
void swap(char a[], char b[])
{
char temp[51];
strcpy(temp, a);
strcpy(a, b);
strcpy(b, temp);
}
void quicksort(char array[10000][51], int start, int end)
{
int i, j, pivot;
if( start < end )
{
pivot = start;
i = start;
j = end;
while( i < j)
{
/* i & pivot */
while( (strcmp(array[i], array[pivot]) <= 0) && i < end )
i++;
/* j & pivot */
while( (strcmp(array[j], array[pivot]) > 0) )
j--;
if( i < j )
{
swap(array[i], array[j]);
}
}
swap(array[pivot], array[j]);
quicksort(array, start, j - 1);
quicksort(array, j + 1, end);
}
}
The way I call it is pretty simple:
int main()
{
int i;
char input[10000][51] = {"this is a test", "another", "fffff", "a" , "skjfkdjf"};
quicksort(input, 0, 4);
/* used to print the strings */
for(i = 0; i < 5; i++)
{
printf("%s\n", input[i]);
}
}
However this throws a trace trap.
If someone could help me find out what is wrong and fix it that would be great!!
Thank you.
The problem is that you're swapping the value with itself here:
swap(array[pivot], array[j]);
I believe:
i = start + 1;
would be a slight optimization, and together with
if (pivot != j) {
swap(array[pivot], array[j]);
}
would be sufficient fix.
I am trying to write a sorting algorithm using a function that finds the adress of the minimum element in the array:
#include <stdio.h>
int * findMin(int * start,int * end) ///function to return the adress of the smallest array element
{
int *min = start;
int x;
int size = (end - start);
for(x=0; x<size; x++)
{
if (*(start+x)<*min)
min = (start+x);
}
return min;
}
But here in my sort algorithm, since the last element has nothing more to compare itself with, is mistakenly left as it is
void sort(int * start, int * end) ///funtion to sort the array in ascending order
{
int x,temp;
int size = (end - start);
for (x = 0; x <size; x++)
{
if ( *(start+x) > *findMin(start,end))
{
temp = *findMin(start+x,end);
*findMin(start+x,end) = *(start+x);
*(start+x) = temp;
}
}
}
int main()
{
int arr[10]={5,11,3,12,17,25,1,9,14,2};
sort(arr,&arr[9]);
for(int i=0;i<10;i++)
printf("%d ",arr[i]);
printf("\n");
}
How can I correct this?
The expression in this declaration
int size = (end - start);
does not give the exact size of the array. At least you should write
int size = end - start + 1;
However it is not a good idea to pass the pointer to the last element of the array instead of the pointer to the memory after the last element of the array. In this case you can specify an empty range as start is equal to end.
Also if the function accepts two pointers then there is no need to introduce intermediate variables used as indices in loops.
And this code snippet
temp = *findMin(start+x,end);
*findMin(start+x,end) = *(start+x);
*(start+x) = temp;
is very inefficient.
Here is a demonstrative program that shows how the functions can be implemented.
#include <stdio.h>
int * findMin( const int * start, const int * end ) ///function to return the adress of the smallest array element
{
const int *min = start;
if ( start != end )
{
while ( ++start != end )
{
if ( *start < *min ) min = start;
}
}
return ( int * )min;
}
void selection_sort( int *start, int *end ) ///funtion to sort the array in ascending order
{
for ( ; start != end; ++start )
{
int *min = findMin( start, end );
if ( min != start )
{
int tmp = *start;
*start = *min;
*min = tmp;
}
}
}
int main(void)
{
int arr[] = { 5, 11, 3, 12, 17, 25, 1, 9, 14, 2 };
const size_t N = sizeof( arr ) / sizeof( *arr );
for ( const int *p = arr; p != arr + N; ++p )
{
printf( "%d ", *p );
}
putchar( '\n' );
selection_sort( arr, arr + N );
for ( const int *p = arr; p != arr + N; ++p )
{
printf( "%d ", *p );
}
putchar( '\n' );
return 0;
}
The program output is
5 11 3 12 17 25 1 9 14 2
1 2 3 5 9 11 12 14 17 25
But here in my sort algorithm, since the last element has nothing more to compare itself with, is mistakenly left as it is
No, that's at best a misleading characterization. Your findMin() does not specifically compare array elements to their immediate successors, so the fact that *end has no successor is irrelevant. The problem is (in part) simply that you have an off-by-one error, resulting in never comparing *end with *min. That mistake would be harder to make and easier to recognize if you relied more directly on pointer arithmetic and comparisons:
int *findMin(int *start, int *end) {
int *min = start;
// The original code is equivalent to this variant:
// for (int *x = start; x < end; x++) {
// but this is what you need for an inclusive upper bound:
// for (int *x = start; x <= end; x++) {
// or, since initially min == start, this would be even better:
for (int *x = start + 1; x <= end; x++) {
if (*x < *min) {
min = x;
}
}
return min;
}
#include <stdio.h>
#define ARRAY_SIZE 10
void lomuto (int A[], int l, int r, int smallerAtLeft)
{
if (smallerAtLeft == 1) //move elements smaller than pivot to the left and the greater ones to the right
{
int tmp, tmp2,pivot,i,j;
pivot = A[r];
i = l-1;
for (j =0; j<r-1; j++)
{
if (A[j] <= pivot)
{
i++;
tmp = A[i];
A[i] = A[j];
A[j] = tmp;
}
}
tmp2 = A[i+1];
A[i+1] = A[r];
A[r] = tmp2;
}
if (smallerAtLeft == 0) //move elements smaller than pivot to the right and the greater ones to the left
{
int tmp3, tmp4,pivot,i,j;
pivot = A[r];
i = l-1;
for (j=0; j<r-1; j++)
{
if (A[j]>= pivot)
{
i++;
tmp3 = A[i];
A[i] = A[j];
A[j] = tmp3;
}
}
tmp4 = A[i+1];
A[i+1] = A[r];
A[r] = tmp4;
}
}
void quicksort (int A[], int l, int r, int ascending)
{
lomuto (A,l,r,ascending);
}
int main()
{
int testarray;
int testArray[ARRAY_SIZE] = {4, 2, 5, 3, 6, 7, 8, 1, 0};
quicksort (testarray,0,8,1);
return testarray;
}
Good evening.
Usually I search almost every forum and deepest threads for dubiety in my codes.
But this time I did not found an answer that could help me. I would be so thankful if anyone could tell my why the code-exe stops working but during compiling there is no error showing onscreen.
We have to implement the quicksort algorithm with the lomuto-partitioning. If the variable "smallerAtLeft" ist equal to 1, the array should be ordered by an increasing property and if its equal to 0 decreasingly.
Furthermore we have to implement to void functions like you see in the code. The "lomuto-fct" and the "quicksort-fct" that contains the lomuto one.
Maybe this Reverse-Lomuto-Thread will help some other people too in the future..
I don't think you understand what the return value from main is and what it's used for. It is usually an indicator of success and failure, with the typical values 0 for success and a small positive value for failure. There are even macros defined for this purpose in the <stdlib.h> header file: EXIT_SUCCESS and EXIT_FAILURE.
If you want to see the sorted array you need to print it:
printf("Sorted array = {");
for (unsigned i = 0; i < ARRAY_SIZE; ++i)
{
printf(" %d", testArray[i]);
}
printf(" }\n");
That of course requires you to pass the actual array to your sorting function.
It should sort with merge. There are two functions the merge and the sort merge. Some not known functions (read array from file and print array) are totally functional in an input file.
Valgrind show me that the failure is at the allocation from array2 and when it read and write at the 3rd while-loop in void merge.
void merge(int* array, int start, int middle, int end) {
int size = end - start + 1;
int *array2 = malloc(size*sizeof(array2));
int k = start;
int m = middle + 1;
int i = 0;
int j = 0;
while ( k <= middle && m <= end ) {
if ( array[k] <= array[m] ) {
array2[i] = array[k];
k++;
}
else {
array2[i] = array[m];
m++;
}
i++;
}
while ( k <= middle ) {
array2[i] = array[k];
k++;
i++;
}
while ( m <= end ) {
array2[i] = array[k];
k++;
i++;
}
while ( j < i ) {
array[ start + j -1 ] = array2[j];
j++;
}
free(array2);
}
void merge_sort(int* array, int first, int last) {
int middle;
if ( first < last ) {
middle = ((first+last) / 2);
merge_sort (array, first, middle);
merge_sort (array, middle + 1, last);
merge (array, first, middle, last);
}
}
int main (int argc, char *argv[])
{
if (argc!=3) {
printf ("usage: %s <maximale anzahl> <dateipfad>\n", argv[0]);
exit(2);
}
char *filename = argv[2];
int *array;
int size = atoi(argv[1]);
array = malloc(size*sizeof(array));
int len = read_array_from_file(array, atoi(argv[1]), filename);
printf("Eingabe:\n");
print_array(array, len);
merge_sort(array, array[0], len);
printf("Sortiert:\n");
print_array(array, len);
free(array);
return 0;
}
At least this is wrong:
int *array2 = malloc(size*sizeof(array2));
I think you mean:
int *array2 = malloc(size * sizeof(*array2));
You want to allocate size times the size of each entry, not the size of the array pointer.
But (on a 64-bit machine) this will actually make your array half the number of bytes, causing your overrun to happen sooner. You have a logic error that you need to figure out by stepping through your code with a debugger.
We have an array, int array={1,2,3};
Display all the possible permutations which will be
{1,3,2} ,
{2,1,3} ,
{2,3,1} ,
{3,1,2} ,
{3,2,1} etc.
all n! possibilities.
I know both ways direct recursive and backtracking too.
Is there any better way to do the same ?
Thank You.
You can use the methods described here.
You can modify his algo slightly for your need:
#include <stdio.h>
void print(const int *v, const int size)
{
if (v != 0) {
for (int i = 0; i < size; i++) {
printf("%c", i ? ',':'{');
printf("%d", v[i] );
}
printf("}\n");
}
} // print
void permute(int *v, const int start, const int n)
{
if (start == n-1) {
print(v, n);
}
else {
for (int i = start; i < n; i++) {
int tmp = v[i];
v[i] = v[start];
v[start] = tmp;
permute(v, start+1, n);
v[start] = v[i];
v[i] = tmp;
}
}
}
int main(void)
{
int v[] = {1, 2, 3};
permute(v, 0, sizeof(v)/sizeof(int));
}
Live example here
As described in other answer, C++ stl library provides an implmentation of next_permutation. You can peep inside stl code and make necessary changes to port it to C code.