Algorithms
Algorithms
printf("%s\n%i\n%li\
n", a.name, a.age,
a.number);
fi
fi
fi
fi
fi
printf("%s\n%i\n%li\
n", a.name, a.age,
a.number);
}
Here, we have used three
different data types to build
a single custom data type.
Then used that data type
inside of a single variable
and stored different
values(of different data
types) using different sub-
containers in to the variable.
We can also declare an
array using custom data
types hence we can make
an array of variables of sub-
variables as well. i.e.;
types hence we can make
an array of variables of sub-
variables as well. i.e.;
typedef struct
{
string name;
int age;
long number;
} person;
int main()
{
person a[3];
a[0].name =
("Sardar Saif Ali");
a[0].number =
923213452897;
a[0].age = 19;
a[1].name =
("Aimash Hassan
Sabri");
a[1].name =
("Aimash Hassan
Sabri");
a[1].number =
92342874534;
a[1].age = 19;
printf("%s\n%li\n%i\
n%s\n%li\n%i\n",
a[0].name,
a[0].number,
a[0].age, a[1].name,
a[1].number,
a[1].age);
}
This is an example of array
declared with custom data
type. Now we can make an
array of arrays(2d array) of
different variables(simple
array) of different sub-
type. Now we can make an
array of arrays(2d array) of
different variables(simple
array) of different sub-
variables(UDT).
UDT stands for user-
de ned types. This
technique is very useful for
making les about
information of people in a
structured way. The
probability of error is very
less and we can store all
information about a
particular person at one
place. These custom data
types can have unlimited
sub-containers. This is a
genuine toolkit of ‘c’ and
involve no abstraction by
fi
fi
fi
types can have unlimited
sub-containers. This is a
genuine toolkit of ‘c’ and
involve no abstraction by
cs50 team(just when using
string data type but thats an
overall abstraction which
can be compensated for
array of characters). So far,
we must declare the
variable with custom data
type rst(separately) and
then initialise different
values to its different sub-
variables using ‘.’ operator
with variable name and then
sub-variable name(each
separately) like we did in
above examples. We
cannot declare the data
fi
fi
fi
sub-variable name(each
separately) like we did in
above examples. We
cannot declare the data
type and then store values
in its sub-variables on same
line(atleast not yet). Structs
are very useful if we want to
store multiple pieces of
information about a single
object.
- If we want to print the
ASCII value of any
character(like the numeral
ASCII value of any
alphabetical character or
anything inside strings), the
character must be a single
character. Not as a whole
string. We can declare char
fi
fi
fi
anything inside strings), the
character must be a single
character. Not as a whole
string. We can declare char
type for single character
and do this or if we want to
do this with the characters
inside of a string, we must
use their separate indexes.
i.e.
string a = “Hi!”;
printf(“%i\n”, a[0]);
We can do this with other
characters as well but we
must use a separate format
speci er and use each
character separately with
their index. Calculations(on
ASCII values) also cannot
be performed on whole
fi
character separately with
their index. Calculations(on
ASCII values) also cannot
be performed on whole
strings. We must use the
characters separately with
their indexes. In short, if we
want to perform any
operation on a string related
to their ASCII value(which is
an integer), we must use
characters of that string
separately.
Sorting:
Sorting is a process of
arranging a set of data in
any particular manner. We
can arrange the data in any
manner like alphabetically,
date added, date modi ed
fi
fi
fi
fi
fi
fi
fi
any particular manner. We
can arrange the data in any
manner like alphabetically,
date added, date modi ed
etc. Sorting is useful when
we have to search for some
data again and again.
Obviously if we have to
search any data only once,
why would we bother taking
all that pain for
implementing an algorithm
for sorting and then
searching for that data? But
if we have any data which
we have to search for again
and again, implementing an
algorithm for sorting rst is
actually useful. Because if
data is sorted we can us
fi
fi
fi
fi
fi
fi
and again, implementing an
algorithm for sorting rst is
actually useful. Because if
data is sorted we can us
more ef cient and swift
search algorithms like
binary search. So if
searching is to be done
again and again, we should
sort the data rst in any
particular manner. There
are different sorting
algorithms that we can use.
Some are easy to
implement but a little
tedious while some are
dif cult to implement but
ef cient and swift.
fi
fi
fi
fi
fi
fi
Selection sort;
In this sorting algorithm, the
control iterates over the
whole set of data. While
iterating, it checks for the
smallest number(or smallest
item according to our
sorting manner), when it
has nished iterating, it
swaps the smallest item it
got at the end with the rst
item of the list. Then it starts
the iteration again, but this
time, from i+1 item(it ignore
the swapped item every
time as i is incremented). It
iterates over the whole list
again and at the end, the
fi
fi
fi
the swapped item every
time as i is incremented). It
iterates over the whole list
again and at the end, the
smallest item it has is
swapped with the rst item
which i+1 item this time. It
repeats the same process
again and again until all the
data is sorted. Every time, it
starts from ahead the
already swapped item(i is
incremented every time). It
is one of those algorithms
which are relatively easy to
implement but very slow.
Like it iterates over the
same data again and again.
Its running time is Θ(n^2).
i.e. in best and worst case
fi
fi
fi
Like it iterates over the
same data again and again.
Its running time is Θ(n^2).
i.e. in best and worst case
scenario, it will take n^2
steps to complete the
sorting. The pseudocode of
such an algorithm is;
For i from 0 to (n-1)
nd smallest number
between numbers[I] and
numbers[n-1]
swap smallest
number with number[I]
increment i every
time
Source code:
int maxvotes = 0;
fi
fi
fi
fi
for (int i = 0;
i < candidate_count;
i++)
{
if
(candidates[i].votes
> maxvotes)
{
maxvotes
=
candidates[i].votes;
}
}
Bubble sort;
In this algorithm, the control
compares a pair of items in
each iteration. It iterates till
the 2nd last item of the
string. When it stars, it
fi
compares a pair of items in
each iteration. It iterates till
the 2nd last item of the
string. When it stars, it
checks the rst 2 items. The
smaller number is swapped
to left while greater
continues. It then
compressed it with next
item, the smallest is again
shifted to left and greater
continues. It compare it with
each element till it goes to
n-2 element. There it
compare it with the last
element and the greatest
element is shifted to
rightmost side. It repeats
this process again and
again until all the items are
fi
element is shifted to
rightmost side. It repeats
this process again and
again until all the items are
sorted. In this algorithm, it
focus more on shifting the
greater item on right side.
Hence, it ignores the last
element every time as it is
already sorted(the greatest
item is shifted to end). So it
ignores the last swapped
element to the end and
iterates over other
remaining pairs. Generally
speaking, this is not very
fast either. Its running time
for upper bound is O(n^2)
but the only optimisation
here is the its running time
fi
fast either. Its running time
for upper bound is O(n^2)
but the only optimisation
here is the its running time
for lower bound is Ω(n).
Thats too if we give it a
condition that if it does not
make any swap, terminate
the program. If we do not do
that, it will just blindly iterate
over the whole process
even if the data is already
sorted. The pseudocode of
such an algorithm is;
Repeat (n-1) times
for i from 0 to (n-2)
if numbers[i] and
numbers[i+1] are out of
order
fi
if numbers[i] and
numbers[i+1] are out of
order
swap them
increment I every
time
if no swaps
quit
In a more broader sight,
both these sorting
algorithms take same
running time and are hence
slow. But there are better
algorithms!
Recursion:
In a vague way, a function
is recursive if it calls itself.
But thats really dont explain
recursion in an easy way.
Albeit, recession is actually
fifi
fi
is recursive if it calls itself.
But thats really dont explain
recursion in an easy way.
Albeit, recession is actually
a function calling itself
inside of itself. But to
understand properly, let’s
take a different approach.
The approach we are going
to take is actually more
closer to iteration.
Sometimes, we have larger
problems in our code that
cant be solved all at once.
So we need to use some
technique, some algorithm,
some function to shrink the
problem, to make it smaller.
Now, the problem is
shrinked but not solved. So
fifi
fi
some function to shrink the
problem, to make it smaller.
Now, the problem is
shrinked but not solved. So
we use the same technique
or function to nibble it down
further. We keep using that
technique again and again
and keep shrinking the size
of the problem until it
reaches the bottom. This is
where the problem is so
shrinked that it cant get any
smaller. Now it must give us
an answer. This is where
we have reached the base
case. And when we were
doing the same technique
again and again to shrink
the problem, we were doing
fifi
fi
case. And when we were
doing the same technique
again and again to shrink
the problem, we were doing
recursion and those were
recursive cases. Recursion
is just using the same
function on a same problem
again and again to shrink its
size. It is a very useful
technique in which the
function calls itself(used
again and again on same
problem) for solving
problems by breaking them
down into smaller, similar
problems. And the point
where it cant get any
smaller further, that is what
base case is. The case
fifi
fi
problems. And the point
where it cant get any
smaller further, that is what
base case is. The case
where we reach the bottom
of any problem by shrinking
it again and again and now
it must give us an answer.
Using recursion is good but
it is a slower technique as it
uses the same algorithm
again and again on the
same problem and also, it is
intricate. But some
problems cant just be
solved without nibbling
them down into smaller
problems and then nally
getting an output. A function
is recursive only if the same
fifi
fi
them down into smaller
problems and then nally
getting an output. A function
is recursive only if the same
function is being applied on
the same problem. If
function or problem(any of
them) is different, the case
is not recursive. Binary
search is an example of
recursion. We use the same
technique of searching on
left or right of middle term
again and again until we
reach the base case that is,
either we are out of terms
and it will return false or we
have found the term and
true is returned. Anyways,
we can literally call a
fifi
fi
and it will return false or we
have found the term and
true is returned. Anyways,
we can literally call a
function inside itself. i.e. it
will do the same process
inside its own self what its
own function is. It’s kind of
iteration thing but not very
similar. In iteration, we just
have to implement any loop
construct once and it will
keep executing again and
again intuitively. However,
in recursion, we have to
write the code or any
technique manually to
actually get the compiler to
execute it again and again.
We can repeat the same
fifi
fi
technique manually to
actually get the compiler to
execute it again and again.
We can repeat the same
code again and again or we
can call a function inside of
its own function(like while
de ning a function, we call it
inside of that) or another
recursion technique.
Recursion actually is a
function calling itself inside
of its own self. Other things
like repeating the same
code on same problem
again and gain can be
called recursion but by
de nition, recursion is when
a function calls itself inside
of it. The former examples
fi
fi
fi
called recursion but by
de nition, recursion is when
a function calls itself inside
of it. The former examples
are more closer to iteration
then to recursion but they
are just easy to swallow the
concept of recursion.
Following is an example of
iteration and recursion for
better distinguishment,
Iteration;
{
for (int i = 0;
i < n; i++)
{
for (int j =
0; j < i+1; j++)
fi
fi
fi
{
printf("#");
}
printf("\n");
}
}
Recursion;
void draw(int n)
{
if (n <= 0)
{
return;
}
draw(n - 1);
for (int i = 0;
i < n; i++)
{
printf("#");
}
printf("\n");
}
Draw function is repeating
the same process inside of
it again. Our rst if
statement is acting as a
base case in this function.
We must give a base case
while using recursion
otherwise it won’t work
fi
base case in this function.
We must give a base case
while using recursion
otherwise it won’t work
properly. Another thing is
we must make an algorithm
to reach base case. Like in
this case we did n-1.
Without this, it would have
not worked properly. So we
must give base case, and
an algorithm to reach that
base case. When a function
is called inside of itself, it
executes itself again from
the start and keep repeating
the process until we reach
the base case. Another
easy implementation is;
fi
the process until we reach
the base case. Another
easy implementation is;
void draw(int n)
{
if (n <= 0)
{
return;
}
for (int i = 0;
i < n; i++)
{
printf("#");
}
printf("\n");
draw(n - 1);
}
fi
In this code, a downward
pyramid is drawn;
#####
####
###
##
#
Here, rst the for loop is
executed and and printed a
row of 5 hashes. Then it
went to new line. Finally,
draw(4) is executed inside
of itself(n - 1). The same
process is repeated again
but with 4 hashes row. Then
draw(3) is executed again
inside of itself. It keep doing
the same until it reached 0
fi
fl
but with 4 hashes row. Then
draw(3) is executed again
inside of itself. It keep doing
the same until it reached 0
which is the base case, so it
is returned and terminated.
This way, we didnt had to
use loops and super uous
code. We just executed the
same function inside of it
with a decrement of 1,
which gave us a perfect
downward pyramid.
void draw(int n)
{
if (n <= 0)
{
return;
fi
fl
}
draw(n - 1);
for (int i = 0;
i < n; i++)
{
printf("#");
}
printf("\n");
}
Lets breakdown our
problem one by one;
First of all, suppose we get
the value of n, initially, as 5.
It will take 5 and go to rst if
statement and check for
5<=0. As it is false, it will
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
the value of n, initially, as 5.
It will take 5 and go to rst if
statement and check for
5<=0. As it is false, it will
not return anything and go
ahead. Then it will
encounter draw(n - 1 = 4)
So now, n is 4 but it does
not have any return value
for draw(4). So it will go
back and execute draw(4).
Remember, draw(5) is still
waiting for an answer in
memory, it is not vanished.
Draw(4) will go to if
statement and as it is false,
it will move ahead. No
return value for draw(4)
either, yet. It will encounter
draw(3) ahead(n(4)-1). It
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
it will move ahead. No
return value for draw(4)
either, yet. It will encounter
draw(3) ahead(n(4)-1). It
will execute the same draw
function moving back to
start of the function and
checking for if statement.
As 3 > 0, it will move ahead
without any return value. It
will then encounter draw(2)
and prepare to execute the
same function for it as well.
Remember, draw(5),
draw(4) ad draw(3), all are
stored inside of memory
waiting to complete their
execution as they had not
reached the end before the
next call was encountered.
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
waiting to complete their
execution as they had not
reached the end before the
next call was encountered.
Draw(2) will repeat the
same process and
eventually encounter
draw(1). Draw(1) will
execute now and encounter
draw(0) nally. All previous
function calls were not
completely executed and
hence waiting for
completion in memory.
Draw(0) will go back to start
and check the if statement.
As 0 = 0, hence it will
encounter a return
statement now. Return
statement tells any user-
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
As 0 = 0, hence it will
encounter a return
statement now. Return
statement tells any user-
de ned function to take that
value(or nothing, if nothing
is written with return), and
give it back to function call
to output it and end that
function at that moment. So
when a function encounter
return statement, it is
terminated right at that
moment no matter how
many lines of code are left
and it return that value(as
answer or simply nothing if
only return statement is
used without any value with
it)to where its function is
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
answer or simply nothing if
only return statement is
used without any value with
it)to where its function is
called(like literally, it
transfers the control to that
line where its function is
called). If there is nothing
written with return, it
terminates the function at
that very moment
irrespective of how many
lines of code are left in that
function and simply
transfers the control to the
line where function is called
and hence the lines ahead
of that function call are
executed wherever function
call is used. However, if
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
and hence the lines ahead
of that function call are
executed wherever function
call is used. However, if
there is any value with
return statement, then it is
terminated at that very
moment and it transfers the
control as well as that
value(which is written with
return)back to where hat
function is called. So if that
function is called inside of a
variable, the value is
transferred and stored in
that variable and control
moves ahead of that
variable. So a return
statement, rst of all,
terminates the function at
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
moves ahead of that
variable. So a return
statement, rst of all,
terminates the function at
that very moment where it is
used, and then if there is no
value along with return
statement, it just transfers
the control back the where
that function is called(and
lines ahead of the function
call are executed) but if
there is a value along with
return statement, then it
transfers that value as well
along with control back to
function call. So a return
statement terminates the
function, and transfer the
control back to where that
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
function call. So a return
statement terminates the
function, and transfer the
control back to where that
function is called. A mere
return function just returns
the control back so that rest
of the code(ahead of
function call) is executed.
As draw(0) has
encountered return, it will
terminate the remaining
code of that function and
simply transfer the control
back to where it was called.
Now, draw(0) was called
just before the for loop
where we had to print a row
for n number of #s. It gets
ahead of that function call
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
just before the for loop
where we had to print a row
for n number of #s. It gets
ahead of that function call
nally, but notice, our n at
that point, is 1. Because it
became 0 in that very
function call when we did 1
- 0,remember draw(n - 1) so
n was actually 1. Hence it
will print only 1 # in rst row.
Finally, a new line and our
draw(1) is also executed
successfully. Draw(1) is
executed with 1 # in rst
row. As we said earlier,
when a function reaches to
its end, it is automatically
returned back to its function
call. If it has any value, it
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
when a function reaches to
its end, it is automatically
returned back to its function
call. If it has any value, it
also returns that value.
Otherwise, only the control
is transferred back. Now
remember, our function
draw(1), was actually called
inside of draw(2), remember
draw(n - 1) so n was
actually 2. Finally, draw(2)
is moving ahead with value
of n as 2. It will encounter
the same loop which prints
the #s for n number of times
in a row. As n is 2 this time,
it will print 2 #s in a row and
as 1 # is already printed
due to draw(1) so we have
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
in a row. As n is 2 this time,
it will print 2 #s in a row and
as 1 # is already printed
due to draw(1) so we have
now 2 back to back rows
with 1 # at rst and 2 at
second. Draw(2) has
reached its end, so it will
transfer the control back to
where it was called.
Interestingly, it called inside
draw(3) where n was
actually 3. Hence it will
move ahead of its function
call and encounter a loop
which prints n number of #s
in a row and as n is 3 this
time, it will print 3 #s in a
row, third row actually
because draw(1) and
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
in a row and as n is 3 this
time, it will print 3 #s in a
row, third row actually
because draw(1) and
draw(2) were already
executed before. Finally,
draw(3) has reached its end
so it transfers the control
back to where it was called
and interestingly again, it
was called inside of draw(4)
where n was 4. So now a
row of 4 #s is printed ahead
of previous 3 rows. Draw(4)
has also reached end,
hence it automatically do
what return statement
would do(even if return
statement is not used but
the function has reached its
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
what return statement
would do(even if return
statement is not used but
the function has reached its
end, it will act as what
return statement would do,
transfer the control back to
where it was called).
Control is transferred to
where it was called and that
is nally, inside of draw(5)
where n is 5. Finally, a 5th
row of 5 #s is printed and
we have a pyramid of height
5. As draw(5) has also
reached its end, it will
transfer the control back to
where it was called which is
now, inside of main
function. So nally we have
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
transfer the control back to
where it was called which is
now, inside of main
function. So nally we have
our pyramid using
recursion.
-Initially, when the control
has not entered a
function(where it is called)
yet, it does not have
permission to pass ahead it,
ignoring it. It must go into it
once. Once it has entered
into a function, then upon
returning(if the function has
reached its end or it
encountered a return
statement) it can go ahead
of that function call, infact, it
will go ahead now and
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
encountered a return
statement) it can go ahead
of that function call, infact, it
will go ahead now and
execute the rest of the code
after that function call. So
without checking any
function, control cant pass
over it without entering it.
But after it has checked
it(went inside), then it will
return eventually to where
function was called and
pass over that line.
Merge sort:
This is another sorting
algorithm but faster and
ef cient then previous ones.
It uses recursion for its
operations. In this
fi
algorithm but faster and
ef cient then previous ones.
It uses recursion for its
operations. In this
algorithm, we use divide
and conquer strategy. It
continuously cuts down a
list into multiple sublists
until each has only one item
and then put those sublists
back but by merging them
in a correct order, thus
sorting the whole list. We
divide the list in two halves.
Then for each divided
halve, we divide them again
in two halves each thus
using recursion. We keep
repeating the same process
until we reach the base
fi
in two halves each thus
using recursion. We keep
repeating the same process
until we reach the base
case which is we just have
one element left in each list.
Then we start the process
of merging. We compare
the divided halves, which
we have eventually, only
one element each. We
merge them in oder then we
compare the other list of
one element. We merge it.
Then these two merged lists
of two elements each are
compared and merged. We
keep repeating the same
process with each half that
we divided until we have
fi
compared and merged. We
keep repeating the same
process with each half that
we divided until we have
our original list sorted
completely. It uses
immense recursion. We sort
the elements while
comparing after dividing
completely. It’s like we
divide them to last limit(one
element each), then we
ascend back by merging
each with each other until
we reaches the very start
from where we started. We
must divide our list in equal
halves and keep dividing
those halves again and
again until we reach the
fi
must divide our list in equal
halves and keep dividing
those halves again and
again until we reach the
lists having one element
each only. Then we should
ascend back and start
merging the halves from
very last pair of elements,
ascending back, merging
them. We have to compare
the pairs with each other
which we divided earlier
and merge them. Finally,
we will have a fully sorted
original list just by dividing
and putting back the
elements but while merging
as well. Its pseudocode is,
fi
and putting back the
elements but while merging
as well. Its pseudocode is,
If only one or less then
one number
Quit
Else
Search left half of
numbers
Search right half of
number
Merge them
Now, by just seeing this
code, we cant comprehend
what’s actually happening.
But what’s actually
happening is recursion
inside of rst two lines of
code. We are repeating the
same code in those two
fi
fi
fi
happening is recursion
inside of rst two lines of
code. We are repeating the
same code in those two
lines again and again until
we reach the base
case(which is a nal pair of
lists with one element
each). Its more detailed
pseudocode would be,
If only one or less then
one number
Quit
Else
Search left half of
numbers
Search left half of
numbers
fi
fi
Search right half of
numbers
Merge them
Search right half of
numbers
Search left half of
numbers
Search right half of
numbers
Merge them
Merge them
This would be a more
detailed pseudocode and
even inn these recursive
cases, there are more
recursive cases similar to
themselves. So in each
search right half code, we
cases, there are more
recursive cases similar to
themselves. So in each
search right half code, we
are again repeating the
original 3 lines of code
again. All of the algorithm
pivot around those 3 lines.
It’s just we have to use
them recursively. Even
more detailed pseudocode
would be,
If only one or less then
one number
Quit
Else
Search left half of
numbers
Search left half of
numbers
Search left half of
numbers
Search right half of
numbers
Merge them
Search right half of
numbers
Search left half of
numbers
Search right half of
numbers
Merge them
Merge them
Search right half of
numbers
Search right half of
numbers
Search left half of
numbers
Search left half of
numbers
Search right half of
numbers
Merge them
Search right half of
numbers
Search left half of
numbers
Search right half of
numbers
Merge them
Merge them
Merge them
Here, we can see more in
detail that how, by only
dividing and putting the
elements back, we can sort
a whole list. We just have to
do little comparing while
putting them back. This
algorithm is very ef cient
and swift but a little intricate
to implement because we
have to use recursion again
and again. The code is very
inclusive as it uses only 3
main lines of code and
whole sorting procedure
pivot around them. Its
running time is Θ(nlogn).
fi
main lines of code and
whole sorting procedure
pivot around them. Its
running time is Θ(nlogn).
Its upper bound and lower
bound, both are same. Its
upper bound is faster than
both, the selection sort and
the bubble sort. However,
its lower bound would only
be faster than selection sort
and slower than bubble sort
because lower bound of
bubble sort is Ω(n) while its
lower bound is Ω(nlogn)
which is slower than Ω(n).
Hence, in terms of upper
bound, our fastest algorithm
is merge sort and in terms
of lower bound, fastest is
fi
Hence, in terms of upper
bound, our fastest algorithm
is merge sort and in terms
of lower bound, fastest is
bubble sort. Selection sort
is slower than both or them
in both bounds. However, in
upper bound, bubble and
selection sort are almost
similar.
- To identify sorting
algorithms(from above 3),
check for the upper bound
rst(unsorted lists),
algorithm that runs fastest
on such lists is merge sort.
Then check for lower
bound(sorted lists),
algorithm that runs fastest
on such lists is bubble sort.
fi
fi
Then check for lower
bound(sorted lists),
algorithm that runs fastest
on such lists is bubble sort.
Finally, our only left option
would be selection sort. So
the remaining algorithm is
obviously selection sort.
Break statement:
It is used to break out of
any loop. It is almost always
used inside of an if-else
statement, inside of a loop
and it breaks out of that
loop. So, inside of a loop,
we use an if-else statement
to make a condition to
break the loop. Inside of
that conditional statement,
we use break statement. So
fi
fi
to make a condition to
break the loop. Inside of
that conditional statement,
we use break statement. So
if that condition is met while
executing, control enters
that if-else statement and
executes the break
statement. Hence, coming
out of that loop right from
that point and ignoring the
rest of the code. It is like the
return statement, but
speci cally for loops. Its
syntax is simple;
break;
We must use it inside of a
conditional to give any
condition for breaking.
However, we can use the
fi
We must use it inside of a
conditional to give any
condition for breaking.
However, we can use the
break statement without any
condition as well, directly
inside of a loop. If a break
statement is used inside of
a nested loop, it just breaks
out of that nested loop, not
from outer loop. So a break
statement is just used for
the loop it is inside of which,
not for its outer loops.
-If we want to nd
something maximum or
minimum we can use this
code;
fi
int maxvotes = 0;
for (int i = 0;
i < candidate_count;
i++)
{
if
(candidates[i].votes
> maxvotes)
{
maxvotes
=
candidates[i].votes;
}
}Problem Set 3:
For minimum, just change
the sign and initial value.
Problem 2(Plurality);
// Update vote
totals given a new
vote
bool vote(string
name)
{
for (int i = 0;
i < candidate_count;
i++)
{
if
(strcmp(name,
candidates[i].name)
== 0)
{
candidates[i].votes+
+;
candidates[i].votes+
+;
return
true;
}
}
return false;
}
printf("%s\n",
candidates[j].name);
}
}
return;
}
Problem 3(Runoff);
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Max voters and candidates
#define MAX_VOTERS 100
#define MAX_CANDIDATES 9
// Array of candidates
candidate candidates[MAX_CANDIDATES];
// Function prototypes
bool vote(int voter, int rank, string
name);
void tabulate(void);
bool print_winner(void);
int find_min(void);
bool is_tie(int min);
void eliminate(int min);
voter_count = get_int("Number of
voters: ");
if (voter_count > MAX_VOTERS)
{
printf("Maximum number of voters
is %i\n", MAX_VOTERS);
return 3;
}
printf("\n");
}
// Eliminate last-place
candidates
int min = find_min();
bool tie = is_tie(min);