Answers to Exam 1 Fri 23 Feb 2001
1. Analyze the following program:
#include
#include
int main(int argc, char *argv[])
{
int k, cnt = 0;
if (argc >= 2)
for (k = 2; k < argc; k++)
if (strcmp(argv[1],argv[k]) > 0) cnt++;
printf("%d\n",cnt);
return 0;
}
The compiler gives the executable version of this program the name a.out.
Suppose we type in the following on the command line :
a.out if me do be it to
For this input line, answer the following questions :
(a) What is the value of argc in the program? 7
(b) What number will be printed by this program? 2
Show your calculations for partial credit if your
answer would be wrong.
if < me
> do +1
> be +1
< it
< to
(c) Explain in words what this program does :
counts the number of words lexicographically less
than argv[1]
+--------+
| /20 |
+--------+
2. The function char *RemoveChar(const char s[], char c);
returns the string s[] with all occurrences
of the character c removed.
For example, RemoveChar("middle",'d') returns "mile".
Write an iterative definition for this function :
char *RemoveChar(const char s[], char c)
{
char *result = (char*)calloc(strlen(s),sizeof(char));
int i,j = 0;
for (i = 0; s[i] != '\0'; i++)
if (s[i] != c) result[j++] = s[i];
result[j] = '\0';
return result;
}
+--------+
| /15 |
+--------+
3. Analyze the code for the following function
int F(const char *s, char c, int k)
{
if (*s == '\0')
return k;
else if (*s < c)
return F(s+1,c,k+1);
else
return F(s+1,c,k);
}
What is returned by F("group",'p',0) ? 2
Execute the code above and complete the table below:
-------------------------------------------
| call | Parameters of F | value |
| |-----------------------| on |
| number | *s | c | k | return |
===========================================
| 1 | "group" | 'p' | 0 | 2 |
| 2 | "roup" | 'p' | 1 | 2 |
| 3 | "oup" | 'p' | 1 | 2 |
| 4 | "up" | 'p' | 2 | 2 |
| 5 | "p" | 'p' | 2 | 2 |
| 6 | "" | 'p' | 2 | 2 |
-------------------------------------------
+--------+
| /15 |
+--------+
4. The Lucas numbers L_n are defined by
L_1 = 1, L_2 = 3,
L_n = L_{n-1} + L_{n-2}, for n > 2.
The function int Lucas(int n); returns the n-th Lucas number.
(a) Give a RECURSIVE implementation of the Lucas function:
int Lucas(int n)
{
if (n == 1)
return 1;
else if (n == 2)
return 3;
else
return Lucas(n-1) + Lucas(n-2);
}
+--------+
| /10 |
+--------+
(b) Give an ITERATIVE implementation of the Lucas function:
int Lucas(int n)
{
int i, previous, current, sum;
if (n == 1)
return 1;
else
{
previous = 1;
current = 3;
for (i = 3; i <= n; i++)
{
sum = previous + current;
previous = current;
current = sum;
}
return current;
}
}
+--------+
| /15 |
+--------+
(c) Which version (iterative or recursive) will be most efficient
to execute? Motivate your answer.
The recursive version will be very inefficient because of
multiple calls to compute the same number many times.
Therefore we prefer the iterative version.
+--------+
| /5 |
+--------+
5. The function char *CurlyChar(char c); returns the string
with curly braces put around the character c.
For example, CurlyChar('k') returns "{k}".
The analogue for strings is done by char *CurlyStr(const char *s).
For example, CurlyStr("exam") returns "{exam}".
Use CurlyChar and CurlyStr to define
char *Curly(int start, int end, const char s[]);
which puts curly braces around the characters s[k]
for start <= k <= \tt end in a nested way. For example,
Curly(0,3,"abcd") returns the string "{{{a}{b}}{{c}{d}}}".
Write a recursive definition for Curly, using CurlyChar and CurlyStr.
You may assume that all strings can have no more than MAX
characters, where MAX is some globally defined constant.
Furthermore, assume that 2.5 gets truncated to 2 if an
integer division of 5 by 2 is performed.
char *Curly(int start, int end, const char s[])
{
int middle;
char *left,*right;
if (start == end)
return CurlyChar(s[start]);
else
{
middle = (start+end)/2;
left = CurlyStr(Curly(start,middle,s));
right = CurlyStr(Curly(middle+1,end,s));
strcat(left,right);
return left;
}
}
+--------+
| /20 |
+--------+