square the array element in O(n) running time - c

Is there a way to square the elements of the array with time complexity of O(n)?
I tried two ways of doing it but I think they are both O(N^2)
PS: I can't use "*", only addition/subtraction.
1.
#include <stdio.h>
int squr(int n, int j){
if(j == 0)
return 0;
else if(j > 0)
return(n + squr(n, j - 1));
else if (n < 0)
return(n + squr(n, j - 1));
}
void loop(int* arr, int count){
for(int n = 0; n < count; n++)
arr[n] = squr(arr[n], arr[n]);
}
2.
void squr(int* arr, int N){
for(int i = 0; i < N; i++){
for(int j = 0; j < i; j++)
sum += i;
arr[i] = sum;
sum = 0;
}
}

Although not likely what OP had in mind, code can use the size of a computed pointer. No *. Of course restricted to n > 0.
int foo(int n, char a[1][n][n]) {
return sizeof a[0];
}
int main(void) {
printf("%d\n", foo(5, 0));
printf("%d\n", foo(100, 0));
return 0;
}
Output
25
10000

Related

Reverse Bubble Sort Algorithm in C using only while loop

I am trying to create a reverse bubble sort algorithm. It works but the first output is a big crazy number that i dont understand. The remaining outputs seem to be sorted in descending order. Where is my code wrong?
#include <stdio.h>
void ft_rev_int_tab(int *tab, int size)
{
int i;
int j;
int k;
i = 0;
while (i < size)
{
j = 0;
while (j < size -i)
{
if (tab[j] < tab[j+1])
{
k = tab[j];
tab[j] = tab[j+1];
tab[j + 1] = k;
}
j++;
}
i++;
}
}
int main(void)
{
int tab[] = {9, 320, 0, 113, 15};
int size = sizeof(tab) / sizeof(*tab);
ft_rev_int_tab(tab, size);
for (int i = 0; i < size; i++)
{
printf ("%d\n", tab[i]);
}
}
i = 0; before while (i < size) is wrong. The condition j < size -i is equivalent to j < size when i is zero. In this case j will be at most size-1 and now tab[j+1] is out-of-range.
It should be changed to i = 1;.
void ft_rev_int_tab(int *tab, int size) {
int i;
int j;
int k;
i = 0;
while (i < size) {
j = 0;
while (j < size - i - 1) {
if (tab[j] < tab[j + 1]) {
k = tab[j];
tab[j] = tab[j + 1];
tab[j + 1] = k;
}
j++;
}
i++;
}
}
Your condition in the nested while loop should be (j < size - i - 1)
because you only need to check the value from tab[0] to tab[i-1]. Your if and swap checks tab[j] and tab[j+1], so when i is equal to the size of the array, you will compare it with a value outside of the array. In your example is the tab[5]'s value.

modified version of selection sort in C

I'm trying to modify selection sort in such a way that it puts the biggest element at the end of the array and then repeats selection sort for n - 1 items until n is 0. My code compiles but the output is still an unsorted array, please help me out!
#include <stdio.h>
void selection_sort(int arr[], int n);
int main ()
{
int n;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
selection_sort(arr, n);
for(int i = 0; i < n; i++)
printf("%d\n", arr[i]);
return 0;
}
void selection_sort(int arr[], int n)
{
if(n <= 0)
return;
while(n > 0)
{
int max = 0;
int temp, x;
for(int i = 0; i < n; i++)
{
if(arr[i] >= max)
max = arr[i];
x = i;
}
temp = arr[n - 1];
arr[n - 1] = max;
arr[x] = temp;
selection_sort(arr, --n);
}
}
The part
if(arr[i] >= max)
max = arr[i];
x = i;
is wrong. You forgot to write {}, so x = i; is executed unconditionally and the swapping after the loop will always be done with the last element. This means that the swapping is done between the same element and it is effectively doing nothing.
Also note that doing both of loop while(n > 0) and recursion selection_sort(arr, --n); is wasteful. You will need only one of that.
Another note is initializing max with 0 will make it behave wrongly when all elements of the input array are negative.
Finally, you should format your code properly with consistent indentation.
Try this:
void selection_sort(int arr[], int n)
{
if(n <= 0)
return;
while(n > 0)
{
int max = arr[0];
int temp, x;
for(int i = 0; i < n; i++)
{
if(arr[i] >= max)
{
max = arr[i];
x = i;
}
}
temp = arr[n - 1];
arr[n - 1] = max;
arr[x] = temp;
--n;
}
}

Get the sorted indices of an array using quicksort

I have changed to quicksort code to sort an array of floats which I got from tutorialgatway.org. However I need the sorted indices. I am aware of the qsort library function that can be used to get the sorted indices and I can implement that. However, I want to avoid standard library (I know this is not recommendation). The reason for not using a standard library is that I need to sort large number of arrays in a loop, which I need to parallelize using openMP, therefore writing function explicitly would allow me to parallelize quicksort function in a loop.
/* C Program for Quick Sort */
#include <stdio.h>
void Swap(float *x, float *y) {
float Temp;
Temp = *x;
*x = *y;
*y = Temp;
}
void quickSort(float a[], int first, int last) {
int i, j;
int pivot;
if (first < last) {
pivot = first;
i = first;
j = last;
while (i < j) {
while (a[i] <= a[pivot] && i < last)
i++;
while (a[j] > a[pivot])
j--;
if (i < j) {
Swap(&a[i], &a[j]);
}
}
Swap(&a[pivot], &a[j]);
quickSort(a, first, j - 1);
quickSort(a, j + 1, last);
}
}
int main() {
int number, i;
float a[100];
printf("\n Please Enter the total Number of Elements : ");
scanf("%d", &number);
printf("\n Please Enter the Array Elements : ");
for (i = 0; i < number; i++)
scanf("%f", &a[i]);
quickSort(a, 0, number - 1);
printf("\n Selection Sort Result : ");
for (i = 0; i < number; i++) {
printf(" %f \t", a[i]);
}
printf("\n");
return 0;
}
How can I return the sorted indices in the code ?
You need to generate an array of indexes from 0 to size-1, then sort the array of indexes according to the array values. So the code does compares using array[index[...]], and does swaps on index[...].
An alternative is to generate an array of pointers from &array[0] to &array[size-1]. When the pointers are sorted, you can convert them to indexes by using: index[i] = pointer[i] - &array[0] (could use a union for the indexes and pointers).
Example program with standard version of Hoare partition scheme to sort array of indexes in I[] according to floats in A[]:
#include <stdio.h>
#include <stdlib.h>
void QuickSort(float A[], size_t I[], size_t lo, size_t hi)
{
if (lo < hi)
{
float pivot = A[I[lo + (hi - lo) / 2]];
size_t t;
size_t i = lo - 1;
size_t j = hi + 1;
while (1)
{
while (A[I[++i]] < pivot);
while (A[I[--j]] > pivot);
if (i >= j)
break;
t = I[i];
I[i] = I[j];
I[j] = t;
}
QuickSort(A, I, lo, j);
QuickSort(A, I, j + 1, hi);
}
}
#define COUNT (4*1024*1024) // number of values to sort
int main(int argc, char**argv)
{
int r; // random number
size_t i;
float * A = (float *) malloc(COUNT*sizeof(float));
size_t * I = (size_t *) malloc(COUNT*sizeof(size_t));
for(i = 0; i < COUNT; i++){ // random floats
r = (((rand()>>4) & 0xff)<< 0);
r += (((rand()>>4) & 0xff)<< 8);
r += (((rand()>>4) & 0xff)<<16);
r += (((rand()>>4) & 0xff)<<24);
A[i] = (float)r;
}
for(i = 0; i < COUNT; i++) // array of indexes
I[i] = i;
QuickSort(A, I, 0, COUNT-1);
for(i = 1; i < COUNT; i++){
if(A[I[i-1]] > A[I[i]]){
printf("error\n");
break;
}
}
free(I);
free(A);
return(0);
}
This version of quicksort avoids stack overflow by only using recursion of the smaller side of the partition. Worst case time complexity will still be O(n^2), but the stack space complexity is limited to O(log(n)).
void QuickSort(float A[], size_t I[], size_t lo, size_t hi)
{
while (lo < hi)
{
float pivot = A[I[lo + (hi - lo) / 2]];
size_t t;
size_t i = lo - 1;
size_t j = hi + 1;
while (1)
{
while (A[I[++i]] < pivot);
while (A[I[--j]] > pivot);
if (i >= j)
break;
t = I[i];
I[i] = I[j];
I[j] = t;
}
/* avoid stack overflow */
if((j - lo) < (hi - j)){
QuickSort(A, I, lo, j);
lo = j+1;
} else {
QuickSort(A, I, j + 1, hi);
hi = j;
}
}
}

Radix sort for 10^6 array in C [duplicate]

This question already has answers here:
Understanding memory allocation, test program crashing
(4 answers)
Closed 7 years ago.
i have this code and it crash in the middle of processing. System gives message "filename.exe stopped working. What is wrong here?
I declare array as global to be able to have so big number of elements, but still it doesn't work.
#include <stdio.h>
#include <stdlib.h>
#define MAX 1000000
#define SHOWPASS
void print(int *a, int n) {
int i;
for (i = 0; i < n; i++)
printf("%d\t", a[i]);
}
void radix_sort(int *a, int n) {
int i, b[MAX], m = 0, exp = 1;
for (i = 0; i < n; i++) {
if (a[i] > m)
m = a[i];
}
while (m / exp > 0) {
int box[10] = { 0 };
for (i = 0; i < n; i++)
box[a[i] / exp % 10]++;
for (i = 1; i < 10; i++)
box[i] += box[i - 1];
for (i = n - 1; i >= 0; i--)
b[--box[a[i] / exp % 10]] = a[i];
for (i = 0; i < n; i++)
a[i] = b[i];
exp *= 10;
#ifdef SHOWPASS
printf("\n\nPASS : ");
print(a, n);
#endif
}
}
int arr[MAX];
int main() {
//int arr[MAX];
int i, num;
printf("\nEnter total elements (num < %d) : ", MAX);
scanf("%d", &num);
printf("\ncreate array : ");
for (i = 0; i < num; i++)
arr[i]=rand()%10;
printf("\nARRAY : ");
print(&arr[0], num);
radix_sort(&arr[0], num);
printf("\n\nSORTED : ");
print(&arr[0], num);
return 0;
}
Here is another code i tried, this time i used malloc. But still it crashes before starting sort. everything is fine if number of elements is <100000.
#include <stdio.h>
#include <stdlib.h>
#define MAX 1000000
#define SHOWPASS
void print(int *a, int n) {
int i;
for (i = 0; i < n; i++)
printf("%d\t", a[i]);
}
void radix_sort(int *a, int n) {
int i, b[MAX], m = 0, exp = 1;
for (i = 0; i < n; i++) {
if (a[i] > m)
m = a[i];
}
while (m / exp > 0) {
int box[10] = { 0 };
for (i = 0; i < n; i++)
box[a[i] / exp % 10]++;
for (i = 1; i < 10; i++)
box[i] += box[i - 1];
for (i = n - 1; i >= 0; i--)
b[--box[a[i] / exp % 10]] = a[i];
for (i = 0; i < n; i++)
a[i] = b[i];
exp *= 10;
#ifdef SHOWPASS
printf("\n\nPASS : ");
print(a, n);
#endif
}
}
int i, num;
int main() {
int* arr = (int*)malloc(MAX * sizeof(int));
int i;
printf("\ncreate array : ");
for (i = 0; i < MAX; i++)
arr[i]=rand()%10;
printf("\nARRAY : ");
print(&arr[0], MAX);
radix_sort(&arr[0], MAX);
printf("\n\nSORTED : ");
print(&arr[0], MAX);
free(arr);
return 0;
}
The bug is here:
int i, b[MAX], m = 0, exp = 1;
Allocating a huge (1 million int) array on the stack is not possible on some if not most systems.
You should malloc the temporary array and allocate only the size needed for the sort, namely n * sizeof(int).
Another problem is this: your radix_sort cannot handle negative numbers.
Less important but worth mentioning: your implementation is not stable. Not a problem for simple int arrays, but potentially incorrect for larger structures.
Furthermore, your code is inefficient: you use division and modulo 10. It would be much faster to use shifting and masking.
Here is a more efficient implementation for large arrays:
#include <limits.h>
#include <string.h>
#include <stdlib.h>
static void radix_sort(int *a, size_t size) {
size_t counts[sizeof(*a)][256] = {{ 0 }}, *cp;
size_t n, i, sum;
unsigned int *tmp, *src, *dst, *aa;
dst = tmp = malloc(size * sizeof(*a));
src = (unsigned int *)a;
for (i = 0; i < size; i++) {
unsigned int v = src[i] + (unsigned int)INT_MIN;
for (n = 0; n < sizeof(*a) * 8; n += 8)
counts[n >> 3][(v >> n) & 255]++;
}
for (n = 0; n < sizeof(*a) * 8; n += 8) {
cp = &counts[n >> 3][0];
if (cp[0] == size) continue;
for (i = sum = 0; i < 256; i++)
cp[i] = (sum += cp[i]) - cp[i];
for (i = 0; i < size; i++)
dst[cp[((src[i] + (unsigned int)INT_MIN) >> n) & 255]++] = src[i];
aa = src;
src = dst;
dst = aa;
}
if (src == tmp) {
memcpy(a, src, size * sizeof(*a));
}
free(tmp);
}

finding index of max value in an array in C

I want to find index of max value in array in C.
I write this code example:
maks=0;
for(i=0;i< N * N;i++) {
if(array[i]>maks) {
maks=(int) array[i];
k=i;
}
}
But this isn't work properly.Could you advise me another example please?
Best Regards...
k = 0;
max = array[k];
for (i = 0; i < N * N; ++i)
{
if (array[i] > max)
{
max = (int)array[i];
k = i;
}
}
Should work !
Below function accepts pointer to array with size of the array as arguments and returns the max index.
int max_index(float *a, int n)
{
if(n <= 0) return -1;
int i, max_i = 0;
float max = a[0];
for(i = 1; i < n; ++i){
if(a[i] > max){
max = a[i];
max_i = i;
}
}
return max_i;
}
Usage example,
float a[3] ={1.2,3.2,4.0};
cout<<max_index(a,3)<<endl; //will output 2, because a[2] element is the max

Resources