Run time or a new idea - c

I need to write code that sorts in 'n' run time and I don't know how to calculate it. I need to simply sort an array so that left side is odd and right side is even. This is what I wrote and I wonder how do I to find the run time.
for (i=0;i<size-1;i++)
{
if(ptr[i]%2==0 || ptr[i]==0)
{
for (j=i;j<size;j++)
{
if(ptr[j]%2!=0)
{
temp=ptr[i];
ptr[i]=ptr[j];
ptr[j]=temp;
break;
}
}
}
}
Thanks in advance.

Your runtime for this Code is O(N^2)
You can use Counting Sort to sort an array in linear time
For reference Counting Sort

As #VenuKant Sahu answered, OP's code is O(n*n)
That is due to its double nested for loops
for (i=0;i<size-1;i++)
...
for (j=i;j<size;j++)
...
I need to write code that sorts in 'n' run time
O(n) algorithm (did not want to just give the code)
The number of loop iterations below can not exceed n/2.
The increment even_side happens at most n times.
The decrement odd_side happens at most n times.
// set up indexes
int even_side = left-most valid index
int odd_side = right-most valid index
loop {
while (the_even_index_is_not_at_the_right_end && is_even(a[even_side]) increment even_side;
while (the_odd_index_is_not_at_the_left_end && !is_even(a[odd_side]) decrement odd_side
compare the indexes
if (done) exit the loop;
a[even_side] <==> a[odd_side]
}
Some helper code to set up a random array.
#define N 10
srand(time(NULL));
int a[N];
for (int i = 0; i<N; i++) {
a[i] = rand()%100;
printf(" %d", a[i]);
}
puts("");

Related

How do I fix this issue with the if statements inside this for loop?

#define MAX 100000
bool hasPair(int array[], int start, int end, int size, int number)
{
int i, temp;
bool binMap[MAX] = {0}; /*initialize hash map as 0*/
for(i = 0; i < size; i++)
{
temp = number - array[i];
if((temp>=0 && binMap[temp] == 1) && (temp != array[i]) && (array[i]>=start && array[i]<=end))
{
printf("The array contains at least one pair which sums up to %d.\n",number); // problem here
return true;
}
binMap[array[i]] = 1;
if(binMap[temp] == 0 && binMap[array[i]] == 0) //and here
{
printf("The array does not contain any pair which sums up to %d.",number);
return false;
}
}
}
I need to write a function which gets an array,its size,the range of its elements(start and end) and a random number as input and the output must be a statement whether there is a pair of different numbers inside the array that their sum equals that random number that we entered as input.I have a problem with the if statements,
because for example:-
an array of 10 elements and the range of these elements is 0-10 the random number is 18 and the arrays elements are:- 0,5,5,2,9,8,2,7,8,2.There wont be any combination of sum between two different numbers of this array which gives us 18
and it works fine in the functions I wrote.
The problem is that for example if we took the same array and this time we substituted 18 for 10 then there will be two different numbers that their sum will be equal to 10 but in my function if I enter this array with random number as 10 then it wont work and I think there is a problem with my If statement so if you can see it whats the problem here?
Your mistake is in the 2nd if condition. It's redundant. You are always invoking this case after the first iteration, and you don't go on for the next iterations.
You should remove the 2nd if condition entirely, and instead add AFTER the for loop a simple statement: return false;.
The idea is you should let the algorithm keep going to the next iterations, even if one was unseccesful. You only return false when you are done with the loop without finding matching elements during it - and only now you can tell no such elements exist.

finding how many times an element has repeated in c

I've got a c study which it must print all the numbers in an array then how many times they repeated.
int lottery(int a,int b,int c,int d,int e,int f,int i,int count)
{
printf("Enter the loop count:");
scanf("%d",&d);
a=time(NULL);
srand(a);
int genel[100][100];
int hepsi[50]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49};
count=0;
for(e=0;e<=d-1;e++)
{
for(b=0;b<=5;b++)
{
genel[e][b]=(rand()%49+1);
while(i>=0 && i<=49)
{
if(genel[e][b]==hepsi[i])
{
count=count+1;
}
else{
count=count;
}
}
printf("%d->%d\t",genel[e][b],count);
}
}
}
This doesnt work obviously. the output must be something like that
1-->0 2-->3 3-->15 etc
TY for your help, cheers :)
It is important that you understand what you are doing, naming is therefore very important. Nesting loops is okay if you know what you are doing. An easier to understand approach would be:
void lottery() {
int i, j //forloop counters
int randArray[100][100]; //array for random values
srand(Time(NULL)); //set random seed based on system time
//set random values
for(i = 0; i < 100; i++) {
for(j = 0; j < 100; j++) {
randArray[i][j] = rand()%49 + 1; //sets random ranging from 1 to 49 (49 incl)
}
}
//here you can start the counting procedure, which I won't spoil but ill give some hints below
}
There are a few options, first the easy lazy approach:
use a loop over all the values, 'int number' from 1 up to 49, inside that forloop use two forloops to search through the whole array, incrementing int x everytime you encounter the value 'number'. After youve searched through the whole array, you can use printf("%d -> %d", number, x); to print the value, set x to zero and count another number.
Another approach is as u tried,
create an array with for each number a location where you can increment a counter. Loop through the whole array now using two for-loops, increment the arraylocation corresponding to the value which youve found at randArray[i][j]. Afterwards print the array with counts using another forloop.
I suggest you try to clean up your code and approach, try again and come back with problems you encounter. Good luck!
sorry if this wasn't helpful to you, I tried to spoil not too much because according to my own experience programming should be learned by making mistakes.

Print the number that appears the maximum number of times in the sequence

Recently I have gone through a problem like this
Write a program to read a sequence of N integers and print the number that
appears the maximum number of times in the sequence.
CONSTRAINTS
1 <= N <= 10000
The integers will be in the range [-100,100]
I have writen the following code:
main()
{int arr[201],max=0,maxelement,n,i,num;
int t;
scanf("%d",&n);
int *storenum=(int *)malloc(sizeof(int)*n);
for(i=0;i<201;i++)
{
arr[i]=0;
}
for(i=0;i<n;i++)
{
scanf("%d",&num);
storenum[i]=num;
if(num<=100 && num>=-100)
{
arr[num+100]=arr[num+100]+1;
}
}
for(i=0;i<n;i++)
{
int t=storenum[i]+100;
if(arr[t]>max)
{ maxelement=storenum[i];
max=arr[t];}
}
printf("\n\n%d",maxelement);
getch();
}
Now I think this code is not optimized one...I want to have a solution that would have less time and space complexity and better solution.
You don't have to iterate through all N items a second time, just iterate through the 201 counts looking for the largest.
Your code looks very close to optimal. It can be made only a little better given your constraints.
Use memset when you mean memset. Yes the compiler will pick it up 99% of the time, but why bother?
for(i=0;i<201;i++) arr[i]=0; // becomes
memset(arr, '\0', sizeof(arr))
The count for any given item can be no larger than 10000. That means it can be held in a ushort!
int arr[201]; // becomes
uint16_t arr[201];
Your second loop should go from for(i = -100; i <= 100; i++) instead, and just loop over arr.
Your code is butt-ugly. Use a consistent indentation, brace style, and don't cram 50 declarations on the same line. Spaces are okay between elements. arr should probably be named something meaningful, I like counts. It kind of looks like you're trying to use gnu style C, but K&R works too, really just pick any style guide and glance through it.

Time complexity of the program

#include<stdio.h>
#include<time.h>
int main()
{
clock_t start;
double d;
long int n,i,j;
scanf("%ld",&n);
n=100000;
j=2;
start=clock();
printf("\n%ld",j);
for(j=3;j<=n;j+=2)
{
for(i=3;i*i<=j;i+=2)
if(j%i==0)
break;
if(i*i>j)
printf("\n%ld",j);
}
d=(clock()-start)/(double)CLOCKS_PER_SEC;
printf("\n%f",d);
}
I got the running time of 0.015 sec when n=100000 for the above program.
I also implemented the Sieve of Eratosthenes algorithm in C and got the running time of 0.046 for n=100000.
How is my above algorithm faster than Sieve's algorithm that I have implemented.
What is the time complexity of my above program??
My sieve's implementation
#define LISTSIZE 100000 //Number of integers to sieve<br>
#include <stdio.h>
#include <math.h>
#include <time.h>
int main()
{
clock_t start;
double d;
long int list[LISTSIZE],i,j;
int listMax = (int)sqrt(LISTSIZE), primeEstimate = (int)(LISTSIZE/log(LISTSIZE));
for(int i=0; i < LISTSIZE; i++)
list[i] = i+2;
start=clock();
for(i=0; i < listMax; i++)
{
//If the entry has been set to 0 ('removed'), skip it
if(list[i] > 0)
{
//Remove all multiples of this prime
//Starting from the next entry in the list
//And going up in steps of size i
for(j = i+1; j < LISTSIZE; j++)
{
if((list[j] % list[i]) == 0)
list[j] = 0;
}
}
}
d=(clock()-start)/(double)CLOCKS_PER_SEC;
//Output the primes
int primesFound = 0;
for(int i=0; i < LISTSIZE; i++)
{
if(list[i] > 0)
{
primesFound++;
printf("%ld\n", list[i]);
}
}
printf("\n%f",d);
return 0;
}
There are a number of things that might influence your result. To be sure, we would need to see the code for your sieve implementation. Also, what is the resolution of the clock function on your computer? If the implementation does not allow for a high degree of accuracy at the millisecond level, then your results could be within the margin of error for your measurement.
I suspect the problem lies here:
//Remove all multiples of this prime
//Starting from the next entry in the list
//And going up in steps of size i
for(j = i+1; j < LISTSIZE; j++)
{
if((list[j] % list[i]) == 0)
list[j] = 0;
}
This is a poor way to remove all of the multiples of the prime number. Why not use the built in multiplication operator to remove the multiples? This version should be much faster:
//Remove all multiples of this prime
//Starting from the next entry in the list
//And going up in steps of size i
for(j = list[i]; j < LISTSIZE; j+=list[i])
{
list[j] = 0;
}
What is the time complexity of my above program??
To empirically measure the time complexity of your program, you need more than one data point. Run your program for multiple values of N, then make a graph of N vs. time. You can do this using a spreadsheet, GNUplot, or graph paper and pencil. You can also use software and/or plain old mathematics to find a polynomial curve that fits your data.
Non-empirically: much has been written (and lectured in computer science classes) about analyzing computational complexity. The Wikipedia article on computational complexity theory might provide some starting points for further reading.
Your sieve implementation is incorrect; that's the reason why it is so slow:
you shouldn't make it an array of numbers, but an array of flags (you may still use int as the data type, but char would do as well)
you shouldn't be using index shifts for the array, but list[i] should determine whether i is a prime or not (and not whether i+2 is a prime)
you should start the elimination with i=2
with these modifications, you should follow 1800 INFORMATION's advice, and cancel all multiples of i with a loop that goes in steps of i, not steps of 1
Just for your time complexity:
You have an outer loop of ~LISTMAX iterations and an inner loop of max. LISTSIZE iterations. This means your complexity is
O(sqrt(n)*n)
where n = listsize. It is actually a bit lower since the inner loop reduces it's count eacht time and is only run for each unknown number. But that's difficult to calculate. Since the O-Notation offers an upper bound, O(sqrt(n)*n) should be ok.
The behaviour is difficult to predict, but you should take into account that accessing the memory is not cheap... it's probably faster to just calculate it again for small primes.
Those run times are too small to be meaningful. The system clock resolution is not accurate to that kind of level.
What you should do to get accurate timing information is run your algorithm in a loop. Repeat it a few thousand times to get the run time up to at least a second, then you can divide the time by the number of loops.

Example of a while loop that can't be written as a for loop

I know a while loop can do anything a for loop can, but can a for loop do anything a while loop can?
Please provide an example.
Yes, easily.
while (cond) S;
for(;cond;) S;
The while loop and the classical for loop are interchangable:
for (initializer; loop-test; counting-expression) {
…
}
initializer
while (loop-test) {
…
counting-expression
}
If you have a fixed bound and step and do not allow modification of the loop variable in the loop's body, then for loops correspond to primitive recursive functions.
From a theoretical viewpoint these are weaker than general while loops, for example you can't compute the Ackermann function only with such for loops.
If you can provide an upper bound for the condition in a while loop to become true you can convert it to a for loop. This shows that in a practical sense there is no difference, as you can easily provide an astronomically high bound, say longer than the life of the universe.
Using C
The basic premise is of the question is that while loop can be rewritten as a for loop. Such as
init;
while (conditional) {
statement;
modify;
}
Being rewritten as;
for ( init; conditional; modify ) {
statements;
}
The question is predicated on the init and modify statements being moved into the for loop, and the for loop not merely being,
init;
for (; conditional; ) {
modify;
}
But, it's a trick question. That's untrue because of internal flow control which statements; can include. From C Programming: A Modern Approach, 2nd Edition you can see an example on Page 119,
n = 0;
sum = 0;
while ( n < 10 ) {
scanf("%d", &i);
if ( i == 0 )
continue;
sum += i;
n++;
}
This can not be rewritten as a for loop like,
sum = 0;
for (n = 0; n < 10; n++ ) {
scanf("%d", &i);
if ( i == 0 )
continue;
sum += i;
}
Why because "when i is equal to 0, the original loop doesn't increment n but the new loop does.
And that essentially boils down to the catch,
Explicit flow control inside the while loop permits execution that a for loop (with internal init; and modify; statements) can not recreate.
While loops can be more helpful when the number of loop iterations are not known while for loops are effective when the loop iterations are known.
Consider the following code snippet for student marks, but the number of students is not known
ArrayList studentMarks = new ArrayList();
int score = 100;
int arraySize = 0;
int total = 0;
System.out.println("Enter student marks, when done press any number less than 0 0r greater than 100 to terminate entrancies\n");
while(score >= 0 && score < 101) {
System.out.print("Enter mark : ");
score = scan.nextInt();
if(score < 0 | score > 100)
break;
studentMarks.add(score);
arraySize += 1;
}
// calculating total, average, maximum and the minimum values
for(int i=0;i<studentMarks.size();i++) {
total += studentMarks.get(i);
System.out.println("Element at [" + (i+1)+"] : " +studentMarks.get(i));
}
System.out.println("Sum of list element is : " + total);
System.out.println("The average of the array list : " + (total/(studentMarks.size())));
Collections.sort(studentMarks);
System.out.println("The minimum of the element in the list is : " + studentMarks.get(0));
System.out.println("The maximum of the element in the list is : " + studentMarks.get(studentMarks.size()-1));
scan.close();
While loop does not have as much flexibility as a for loop has and for loops are more readable than while loops. I would demonstrate my point with an example. A for loop can have form as:
for(int i = 0, j = 0; i <= 10; i++, j++){
// Perform your operations here.
}
A while loop cannot be used like the above for loop and today most modern languages allow a for each loop as well.
In my opinion, I could be biased please forgive for that, one should not use while loop as long as it is possible to write the same code with for loop.
In C-like languages, you can declare for loops such as this:
for(; true;)
{
if(someCondition)
break;
}
In languages where for is more strict, infinite loops would be a case requiring a while loop.

Resources