How many times is the function called in this C code? - c

This code should show how many times the Sort function is called when we have a range of array starting with l and ending with r. Note that the goal isn't showing the sorted array. So it uses mergesort but I deleted the merge step because the goal is just finding out how many times the Sort function is called.
I don't know which part of the code is wrong and why I can't get the correct answer.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
int counter;
bool isSorted (int array[], int l, int r)
{
bool flag;
int i;
int size=l-r+1;
if (size==0 || size==1)
flag=true;
for (i=l; i<r-1 ; i++)
{
if (array[i]<array[i+1])
flag=true;
else
flag=false;
}
return flag;
}
void Sort(int A[], int l, int r) {
// Sorts [l, r)
if (!isSorted(A, l, r))
{
counter=counter+2;
int mid = (l + r) / 2;
Sort(A, l, mid);
Sort(A, mid, r);
}
}
int main()
{
int number,length,c,d,k;
scanf("%d %d", &length, &number);
int l[number],r[number];
int a[length];
for (c = 0; c < length ; c++)
scanf("%d", &a[c]);
for (d = 0; d < number ; d++)
scanf("%d %d", &l[d], &r[d]);
void TASort(int A[],int l,int r);
for(k=0; k<number ; k++)
{
counter=1;
Sort(a,l[k],r[k]);
printf("%d\n", counter);
}
return 0;
}
Two numbers in the first line o input show the number of elements in the array and the number of ranges that the user wants(Using l and r).
For Example:
Input:
8 2
34 7 11 27 2 35 32 16
1 5
3 7
Output:
5
3

You need to look at your function isSorted(). When there are three or more items of data to look at, there will be two or more comparisons. Each time you set flag you don't take into account its current value. This means that the isSorted() function will return true if the last two items it compared were sorted irrespective of whether the previous ones were.

Related

Array to int and Sum of them in C

im learning C and i am a bit confused with array handling.
I have a task that asks me to sum up 2 arrays of non negative integers.
example array 1 = {1,2,3} , array 2 = {4,5,6} -> 123+456 = 579
I searched a bit for a solution on how to convert those arrays of integers to an integer, but didnt really get helpful information.
I ended up with a code:
#include <stdio.h>
int sum(int A[],int B[], int n){
int i,j,t,k;
for(i=0;i<n;i++){
t= t+A[i];
}
for(j=0;j<n;j++){
k= k+B[j];
}
return t+k;
}
int main()
{
int n = 3;
int a[n] = {1,2,3};
int b[n] = {4,5,6};
printf("%d",sum(a,b,n));
return 0;
}
But my result is 1225283 which of course is wrong.
I found a solution where people write something like "t= 10* t+A[i]" , i dont get where that "10* " comes from, but i tested it and then "t" gets "123" but if i try the same for "k" it doesnt work, returning "k" doesnt give me "456". I am a bit confused, whats the proper way of handling this problem?
Thanks for any help.
You're basically adding digits 1+2+3 instead of creating the number 123. Your code also has various other flaws, like uninitialized variables. Here is a working example:
int array2int(int A[], int n) {
int ret = 0;
for(int i=0, k=1; i<n; i++){
ret = ret + k * A[i];
k *= 10;
}
return ret;
}
int sum(int A[],int B[], int n){
return array2int(A, n) + array2int(B, n);
}
First of all, in sum function, you haven't initialized neighter t nor k but you keep summing them and use later, so every time your code is executed, you chould get different result.
On the other hand, in something like "t= 10 t+A[i]", 10 comes from basic math, where a number could be resolved as a10^0 + b10^1 +c*10^2 + .... + m * 10^n. As a result, starting from least significant digit, everytime you try to add new digit (from least to most significant), you need your multipliciant to be 10 times greater.
int sum(int A[],int B[], int n){
int i,j,t=0,k=0,ten=1;
for(i=n-1;i>=0;i--){
t += ten*A[i];
ten *= 10;
}
ten = 1; /* initialize again*/
for(j=n-1;j>=0;j--){
k += ten*B[j];
ten *= 10;
}
return t+k;
}
Something like that should work.

C Binary & Linear Search

Hello i want to draw the time/array size graph for binary and linear search algorithms.(Worst, best and average case for array size = 1 000, 10 000,100 000,1 000 000). I'm using DEV C++. However, when i run the code for array size = 1 000 000, the program crashes. Here is the code :
#include <stdio.h>
int binarySearch(int arr[], int l, int r, int x)
{
if (r >= l)
{
int mid = l + (r - l)/2;
if (arr[mid] == x) return mid;
if (arr[mid] > x) return binarySearch(arr, l, mid-1, x);
return binarySearch(arr, mid+1, r, x);
}
return -1;
}
int main(void)
{
int arr[10] = {2,5,8,9,15,18,19,25,34,50};
int n = sizeof(arr)/ sizeof(arr[0]);
int x = 10;
int result = binarySearch(arr, 0, n-1, x);
(result == -1)? printf("Element is not present in array")
: printf("Element is present at index %d", result);
return 0;
}
You are allocating array arr on stack. For 1 000 000 elements you need 4 MB of memory (assuming that sizeof(int) == 4). On Windows for example most of cases stack has default limit of 1 MB. For quick fix define arr as static
static int arr[size];
or put in global scope outside function body or as others said, use dynamic allocation.

qsort(): Sorting only even numbers of an array

I'm trying to use the qsort() function in order to sort only the even numbers of an array (the odds remains in their positions).
For instance if I have the array:
5 122 3 26 48
After sorting one would get:
5 26 3 48 122
My intuition was only to make a sort when both numbers pointed by a and b are even.
This is my attempt:
#include <stdio.h>
#include <stdlib.h>
int comp_even(const void *a, const void *b) {
int l = *(int *)a;
int r = *(int *)b;
if ( !(l&1) && !(r&1) ) //if both are even, then sort them in ascending order
return (l-r);
return 0;
}
int main() {
int i, n;
int a[1001];
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
qsort(a, n, sizeof(int), comp_even);
for (i = 0; i < n; i++) {
printf("%d ", a[i]);
}
return 0;
}
Unfortunately, qsort doesn't support anything like that; for any two elements, the comparison function must return one of three results:
a negative integer, meaning that its first argument should end up before its second;
a positive integer, meaning that its first argument should end up after its second;
zero, meaning that either ordering is fine (in which case qsort makes no guarantees about which element ends up before the other).
And, crucially, the function must do this using only the values of its two arguments; it doesn't know the array-indices that they came from.
Instead, you can take one of two approaches:
copy all of the even elements into an array, sort that array using a straightforward comparison function, and then copy the elements of that array back over the even elements in the original array.
create an int[][2] that stores not just the values in the array, but also their original indices. You can then sort the elements such that if either value is odd, then the element with the lesser original index comes first.
It seems impossible to design a comparison function for your purpose, but you can make a copy of the even numbers, sort that with qsort and dispatch the sorted subset over the even numbers of the original array:
#include <stdio.h>
#include <stdlib.h>
int comp_int(const void *a, const void *b) {
const int *ap = a;
const int *bp = b;
return (*ap > *bp) - (*ap < *bp);
}
int main(void) {
int i, j, n, n_even;
int a[1001];
int even[1001];
if (scanf("%d", &n) != 1 || n <= 0 || n > 1001)
return 1;
n_even = 0;
for (i = 0; i < n; i++) {
scanf("%d", &a[i]);
if ((a[i] & 1) == 0) {
even[n_even++] = a[i];
}
}
qsort(even, n_even, sizeof(int), comp_int);
for (i = j = 0; i < n; i++) {
if ((a[i] & 1) == 0) {
a[i] = even[j++];
}
for (i = 0; i < n; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
Note also that your original comparison function uses a trick to compare integers that fails for large values. The difference of 2 integers may be outside the range of int. So returning l - r may be incorrect for many values of l and r.
For example l=INT_MIN and r=1 will return INT_MIN-1, the subtraction causes an arithmetic overflow, which invokes undefined behavior and in current 2s complement architectures evaluates to INT_MAX, a positive value although INT_MIN < 1.

Comparing two arrays of integers and returning the subscript (C)

(a newer version of my program is right in the end)
I need to create a program with a function that compares two arrays of integers and returns the subscript of the first place they differ.
I have to use a sentinel value to indicate the end of valid input, rather than EOF, as a file cannot have two end-of-files.
Example of my desired input and output for my program:
Input 1:
3 4 5
3 4 6
Output 1:
2
Explanation: the third values of two arrays are different, so it prints the third subscript (counting as 0,1,2).
I looked over similar issues on stackoverflow. Many errors were fixed and now it lets me to compile a program, without giving me any errors or warnings. But it blinds me because I don't understand what exactly doesn't work.
My problem that I encounter:
When I press Enter button after the first value, the program stops working.
I assume my tableDiff function is wrong, however I copied it from teacher's notes. Unless I made a typo, there shouldn't be any difference.
Here is my submitted version:
/*
* A simple program to sort numbers in the correct order
*/
#include <stdio.h>
#include <stdlib.h>
#define MAX 10 //max elements in array
#define SENTINEL -999 //indicate the end of valid input
int main () {
int tableFill(int a[], int max);
int tableDiff (const int a[], const int b[], int n, int m);
void tablePrint (const int a[], const int b[], int n, int m);
int a[MAX];
int b[MAX];
int m,n,index;
m = tableFill(a, MAX);
n = tableFill(b, MAX);
tablePrint(a,b,n,m);
index = tableDiff(a,b,m,n);
if(index==-1)
printf("Index is the same");
else
printf("Index is the different");
return 0;
}
// read values from stdin into array up to 'max' values
int tableFill(int a[], int max) {
int r; // input from scanf
int next; // next input value
int cnt = 0; // count of values read
int *ptr; //pointer
printf("Enter the numbers! \n");
while ((r=scanf("%i", &next)) == 1 && next != SENTINEL)
{
if (r == 0) //invalid input data
{
printf("Nonnumeric data entered. Please enter a number. \n");
while (getchar()!= '\n'); // flush invalid data
}
else
*ptr++=cnt;
}
if(r==1) //another value was read but the array is full
printf("Error - too many values. Array size %i.\n", max);
return ptr-a; //(ptrb - b) should return the same value
}
int tableDiff (const int a[], const int b[], int n, int m)
{
const int *ptra = a; //start for 1st array
const int *ptrb = b; //start for 2nd array
const int *endptra = a+m; //end for 1st array
const int *endptrb = b+n; //end for 2nd array
while(ptra<endptra && ptrb<endptrb && *ptra==*ptrb)
{
ptra++;
ptrb++;
}
if( ptra==endptra && ptrb==endptrb)
{
return -1;
}
else
return ptra -a; //(ptrb - b) should return the same value
}
//print all elements in array.
void tablePrint (const int a[], const int b[], int n, int m)
{
int i; //varriable to print
for (i = 0; i < n; i++)
printf ("%d ", a[i]);
printf ("\n");
}
Here is my newer version:
The program now continues to work until reaches second sentinel (works correctly).
/*
* A simple program to sort numbers in the correct order
*/
#include <stdio.h>
#define MAX 10 //max elements in array
#define SENTINEL -999 //indicate the end of valid input
int main () {
// read values from stdin into array up to 'max' values
int tableFill(int a[], int max);
//compare two arrays and returns the first subscript they differ
int tableDiff (const int a[], const int b[], int n, int m);
//print all elements in array
void tablePrint (const int a[], int n);
int a[MAX];
int b[MAX];
int m,n,index;
m = tableFill(a, MAX);
n = tableFill(b, MAX);
tablePrint(a,m);
tablePrint(b,n);
index = tableDiff(a,b,m,n);
if(index==-1)
printf("-1. Arrays are the same.");
else
printf ("\n The arrays differ at index '%d'.\n", index);
return 0;
}
// read values from stdin into array up to 'max' values
int tableFill(int a[], int max) {
int r; // input from scanf
int next; // next input value
int cnt = 0; // count of values read
int *ptr = a; //pointer
printf("Enter the numbers! \n");
while ((r=scanf("%i", &next))==0 || (next != SENTINEL))
{
if (r == 0) //invalid input data
{
printf("Nonnumeric data entered. Please enter a number. \n");
while (getchar()!= '\n'); // flush invalid data
}
else if (cnt == max) //another value was read but the array is full
printf("Error - too many values. Array size %i.\n", max);
else {
*ptr++ = next;
++cnt;
}
}
return ptr-a; //(ptrb - b) should return the same value
}
//compare two arrays and returns the first subscript they differ
int tableDiff (const int a[], const int b[], int n, int m)
{
const int *ptra = a; //start for 1st array
const int *ptrb = b; //start for 2nd array
const int *endptra = a+m; //end for 1st array
const int *endptrb = b+n; //end for 2nd array
while(ptra<endptra && ptrb<endptrb && *ptra==*ptrb)
{
ptra++;
ptrb++;
}
if( ptra==endptra && ptrb==endptrb)
{
return -1;
}
else
return ptra -a; //(ptrb - b) should return the same value
}
//print all elements in array
void tablePrint (const int a[], int n)
{
int i; //loop counter
for (i = 0; i < n; i++)
printf ("%d ", a[i]);
printf ("\n");
}
You have a number of issues in your logic. The first of which in
while ((r=scanf("%i", &next)) == 1 && next != SENTINEL)
prevents the remainder of the code within the loop from ever executing in the event a non-numeric value is entered. If r != 1, you exit the loop, not process further within it.
While not an error, function prototypes within main only works when the functions exclusively do not rely on each other. They know nothing about one another during execution. Better to move the prototypes above main.
The remainder of your logic was somewhat difficult to follow and overly complicated. When you are looking for a difference within two arrays, you only need iterate over common elements. If they have differing number of elements, you know they differ by definition starting at the first unique element. So you can whittle down your comparison code quite a bit. Something like the following is fine:
/* check if array 'a' and 'b' are the same, else return index
* of first difference, otherwise return -1 for equal arrays.
*/
int tablediff (const int *a, const int *b, int sza, int szb)
{
int i, lim = sza < szb ? sza : szb; /* limit search to common elements */
for (i = 0; i < lim; i++) /* for each common element check */
if (a[i] != b[i])
return i;
if (sza != szb) /* if size differs, arrays differ */
return lim;
return -1; /* otherwise equal */
}
You can avoid the use of a SENTINEL just by proper bounds checking. Further, while you are free to create a arrayprint function that prints 2 arrays, it is far better to create a function that prints a single array and call it twice.
Putting those pieces together, and noting you do not use anything from stdlib.h, you could do something similar to the following:
#include <stdio.h>
#define MAX 10 //max elements in array
int tablefill(int *a, int max);
int tablediff (const int *a, const int *b, int sza, int szb);
void tableprn (const int *a, int sza);
int main (void) {
int a[MAX];
int b[MAX];
int idx, sza, szb;
sza = tablefill (a, MAX);
szb = tablefill (b, MAX);
tableprn (a, sza);
tableprn (b, szb);
if ((idx = tablediff (a, b, sza, szb)) == -1)
printf ("\n the arrays are the same.\n\n");
else
printf ("\n the arrays differ at index '%d'\n\n", idx);
return 0;
}
/* read values from stdin into array up to 'max' values */
int tablefill (int *a, int max)
{
int idx = 0, tmp;
while (idx < max && scanf (" %d", &tmp) == 1)
a[idx++] = tmp;
return idx;
}
/* check if array 'a' and 'b' are the same, else return index
* of first difference, otherwise return -1 for equal arrays.
*/
int tablediff (const int *a, const int *b, int sza, int szb)
{
int i, lim = sza < szb ? sza : szb;
for (i = 0; i < lim; i++)
if (a[i] != b[i])
return i;
if (sza != szb)
return lim;
return -1;
}
/* print all elements in array. */
void tableprn (const int *a, int sz)
{
int i; //varriable to print
for (i = 0; i < sz; i++)
printf (" %d", a[i]);
printf ("\n");
}
Example Equal
$ /bin/arraycmp <../dat/20intsame.txt
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1495
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1495
the arrays are the same.
Example Differ
$ ./bin/arraycmp <../dat/20intdif.txt
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1495
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1494
the arrays differ at index '9'
Providing Prompts for Input
When taking user input, it is a good idea to proving meaningful prompts as well so the user isn't left looking at a blinking cursor wondering if the program has hung, or what is going on. So in addition to the logic above, you would want to add simple prompting that explains what the program needs and how to provide the input. Something simple will do:
printf ("\nenter a max of 10 integers below 'ctrl+d` to end.\n");
sza = tablefill (a, MAX);
printf ("enter a max of 10 integers below 'ctrl+d` to end.\n");
szb = tablefill (b, MAX);
printf ("\nthe arrays entered are:\n\n");
tableprn (a, sza);
tableprn (b, szb);
(note: to generate a manual EOF on windoze, the key combination is ctrl+z)
So for entering less than 10 integers for each array you could do something like:
$ ./bin/arraycmp
enter a max of 10 integers below 'ctrl+d` to end.
10 12 14 16 17
enter a max of 10 integers below 'ctrl+d` to end.
10 12 14 15 17
the arrays entered are:
10 12 14 16 17
10 12 14 15 17
the arrays differ at index '3'
Look over the example and let me know if you have any additional questions.

transpose non-square matrix in C

everyone I am trying to work on the transpose matrix
here is my code so far.
void Transpose(int mt[][10], int m, int n)
{
int c,d,temp;
for (c = 0; c < m; c++)
{
for (d = c+1; d < n; d++)
{
temp = mt[c][d];
mt[c][d]=mt[d][c];
mt[d][c] = temp;
}
}
}
void print(int pose[][10], int m, int o)
{
int i,j;
for(i = 0; i < m; i++)
{
for(j = 0; j < o; j++)
{
printf("%d\n",pose[j][i]);
}
}
}
int main()
{
/*The body of your source code will go here */
int a[4][5] = {{1,2,3,4,5},{6,7,8,9,10},{10,9,8,7,6},{5,4,3,2,1}};
printf("ARRAY: %d",a[][5]);
Transpose();
return (0);
}
Here is my function for print and transpose a matrix, but now I am trying to pass the array into the function from my main. I just wondering how I declare the array that in the main can pass to the function. Thanks
Your declaration of Transpose does not match your use of it. Since it is declared as:
void Transpose(int mt[][10], int m, int n) {...}
It should be invoked by
Transpose(a, 4, 5);
Also, what is the 10 for? And, the statement
printf("ARRAY: %d", a[][5]);
is unlikely to work.
You should choose better names for your variables. Instead of m and n, use nRows and nColumns. Use row and column instead of i and j.
You can use the following code to do it.
#include<stdio.h>
// Print Matrix
void printArr(int *A, int row,int col)
{
int i,j;
for(i=0;i<row;i++)
{
printf("\n");
for(j=0;j<col;j++)
printf("%d\t",*(A+(col*i)+j));
}
}
//Find the Transpose(TA) of Matrix(A)
void Transpose(int *A,int *TA,int row,int col)
{
int i,j;
for(i=0;i<row;i++)
for(j=0;j<col;j++)
*(TA+(j*row)+i)=*(A+(col*i)+j);
}
// Start of Main
int main()
{
int A[4][5]={{1,2,3,4,5},{6,7,8,9,10},{10,9,8,7,6},{5,4,3,2,1}};
int *TA=malloc(sizeof(int)*4*5); // Allocate Memory for TA
int i,j;
printf("Matrix A:");
printArr(A,4,5); //Print Array A
Transpose(A,TA,4,5); //Call Transpose
printf("\nTranspose Matrix A:");
printArr(TA,5,4); // Print Array TA
return 0;
}
Output:
Matrix A:
1 2 3 4 5
6 7 8 9 10
10 9 8 7 6
5 4 3 2 1
Transpose Matrix A:
1 6 10 5
2 7 9 4
3 8 8 3
4 9 7 2
5 10 6 1
The C programming language does not remember the lengths of arrays like other programming languages do. That makes working with multidimensional arrays difficult.
To pass a multidimensional array as a parameter in C, you either have to know the dimensions of the array at compile time:
#define HEIGHT 10
#define WIDTH 13
void function_prototype(int M[HEIGHT][WIDTH]) {
access M normally with M[y][x]
}
or you have to pass a single dimensional array and the lengths as parameters:
void function_prototype(int* M, int height, int width) {
access M as M[y * width + x]
}
It's troublesome, but that's the price you pay for having extremely fast array access.

Resources