CS1010 Notes
  • Welcome
  • Lec/Tut/Lab/Exes
    • Lecture
      • Lec 01 - Computational Problem Solving
      • Lec 02 - Functions and Types
      • Lec 03 - Basic C Programming
      • Lec 04 - Conditionals
      • Lec 05 - Loops
      • Lec 06 - Call Stacks, Arrays
        • Diagnostic Quiz
      • Lec 07 - Pointers, Memory management
        • Diagnostic Quiz
      • Lec 08 - Multi-d Array, Efficiency
        • Diagnostic Quiz
      • Lec 09 - Searching and Sorting
        • Diagnostic Quiz
      • Lec 10 - More Recursion
        • Diagnostic Quiz
      • Lec 11 - Strcut & Standard I/O
        • Diagnostic Quiz
      • Lec 12 - Recap
    • Tutorial
      • Tut 01 - Computational Problem-Solving
      • Tut 02 - Functions and Conditionals
      • Tut 03 - More on Conditionals
      • Tut 04 - Loops
      • Tut 08 - Searching and Sorting
    • Lab
      • Lab 01 - Unix/Vim Setup
      • Lab 02 - Debugging
      • Lab 03 - Assert
      • Lab 04 - Test Cases
      • Lab 05 - Arrays
      • Lab 06 - Memory Errors
      • Lab 07 - Compiling with Clang
      • Lab 08 - C Preprocessor
      • Lab 09 - Backtracking
      • Lab 10 - Struct and Wrap up
    • Exercises
      • Exercise 3 - Fixed-Length Arrays
      • Exercise 4 - Dynamic Arrays and Strings
      • Exercise 6 - Searching and Sorting
      • Exercise 7 - More Recursion
      • Exercise 8 - Struct
  • Past Year Exam
    • Midterm PE
      • PE1 (AY18/19)
      • PE1 (AY20/21)
      • PE1 (AY21/22)
      • PE0 (AY22/23)
      • PE0 (AY23/24)
    • Midterm Paper
      • Midterm (AY18/19)
      • Midterm (AY20/21)
      • Midterm (AY21/22)
      • Midterm (AY22/23)
    • PE1 Review
      • PE1 (AY23/24)
    • PE2 Review
      • PE2 (AY18/19)
      • PE2 (AY20/21)
      • PE2 (AY21/22)
      • PE2 (AY22/23)
      • PE2 (AY23/24)
    • Final Paper
      • Final (AY18/19)
      • Final (AY20/21)
      • Final (AY21/22)
      • Final (AY22/23)
      • Final (AY23/24)
  • Current Year Exam
    • PE0 (AY24/25)
    • PE1 (AY24/25)
    • PE2 (AY24/25)
    • Final (AY24/25)
  • Toolbox
    • Vim & Unix
    • GDB
  • After CS1010
Powered by GitBook
On this page
  • Problems
  • 1. Tic Tac Toe
  • 2. Sun
  • 3. Replace*
  • 4. Soil
  • 5. Substring*
  • Tips
Edit on GitHub
  1. Past Year Exam
  2. PE2 Review

PE2 (AY20/21)

PreviousPE2 (AY18/19)NextPE2 (AY21/22)

Last updated 6 months ago

Problems

Questions:

Official Answers:

1. Tic Tac Toe

An easy probelm, just break this problem into several small problems and solve it.

2. Sun

The whole idea is to find the max num (index) that provides the biggest "triangle" number smaller than the input n. And then we start from that triangle number to find its corresponding prime partner. (Cuz the probelms says triangle num should be in decreasing order)

for (max = 0; tri <= n; max += 1)
{
  tri = max * (max + 1) / 2;
}
for (long x = max - 2; x >= 0; x -= 1)
{
  tri = x * (x + 1) / 2;
  if (is_prime(n - tri))
  {
    cs1010_print_long(n - tri);
    cs1010_print_string(" ");
    cs1010_println_long(tri);
  }
}

But the overall run time of O(N)O(N)O(N) is a bit tricky. Here our first loop is actually O(N)O(\sqrt{N})O(N​) and our second loop is actually one O(N)O(\sqrt{N})O(N​) loop inside another O(N)O(\sqrt{N})O(N​) loop, so the overal timing is O(N)+O(N)O(N)+O(\sqrt{N})O(N)+O(N​), which is O(N)O(N)O(N)

3. Replace*

The official answer

The idea of replacing the redundant chars in the target string with white spaces and then ignore them in the final print is awesome.

Substitute.c
void substitute(char *word, size_t i, size_t target_len, char *replace_with) {
    size_t replace_len = strlen(replace_with);
    size_t j = 0;
    while (j < replace_len) {
        word[i + j] = replace_with[j];
        j += 1;
    }
    while (j < target_len) {
        word[i + j] = ' ';
        j += 1;
    }
}

There is an awesome idea here! The use of i to indicate the start position in the source string we want to search for deals with the moving problem of the string successfully.

Here it is assumed that the length of the target string is longer than or equal to the length of the replace string.

Compact.c
void compact(char *word)
{
    size_t src = 0;
    size_t dst = 0;
    size_t word_len = strlen(word);
    while (src < word_len) {
        if (word[src] != ' ') {
            word[dst] = word[src];
            dst += 1;
        }
        src += 1;
    }
    word[dst] = 0;
}

Based on the same assumption above, our dst is always smaller than or equal to src

Replace.c
void replace(char *word, char *search_for, char *replace_with)
{
    size_t word_len = strlen(word);
    size_t search_len = strlen(search_for);
    for (size_t i = 0; i < word_len; i += 1) {
        if (is_match(word, i, search_for)) {
            substitute(word, i, search_len, replace_with);
            i += search_len ­- 1;
        }
    }
    compact(word);
}

My Recursive solution

Refer to the idea of doing recursion on strings from past year final paper (AY21/22 Q19) I implement a recursive solution as follows:

void search_and_replace(char *tar, char *rep, long tar_len, long rep_len, char *res, char *source)
{
  long len_res = 0;
  long len_src = 0;
  if (*source == '\0')
  {
    return;
  }
  long start_pos = find_pos(tar, source);
  if (start_pos != -1)
  {
    for (long i = 0; i < start_pos; i += 1)
    {
      res[i] = source[i];
    }
    len_res += start_pos; 
    for(long i = 0; i < rep_len; i += 1)
    {
      res[i+len_res] = rep[i];
    }
    len_res += rep_len;
    len_src = start_pos + tar_len;
  }
  else
  {
    char *temp = source;
    while (*temp != '\0')
    {
      res[len_src] = source[len_src];
      len_src += 1;
      temp += 1;
    }
    len_res = len_src;
   }
  search_and_replace(tar, rep, tar_len, rep_len, res+len_res, source+len_src);
}

Note that this function will need some tedious memory management in the main() function, where we need to read several target strings and replacement strings.

4. Soil

Prof summarises this problem to be a pattern recognition problem. The soul of this problem is the narrow your "searching area". That is, we can start from top-right (a[0][n-1])

  1. If a[0][n-1] is bigger than q, that means q cannot exist in the last column, so we narrow our search area by excluding the last column.

  2. If a[0][n-1] is smaller than q, that means q cannot exist in the first row, so we narrow our search area by excluding the first row.

5. Substring*

This question also utilizes the awesome use of "move string" when pass it in recursion. The use of each parameter in the fucntion are documented in the code below:

/**
 * @param src  The source string
 * @param len  The length of source string
 * @param k    The length of the remaining characters
 * @param curr The position / Number of characters we have appended
 * @param sub  The substring
 */
void print_sub(char *src, size_t len, size_t k, size_t curr, char *sub)
{
  // No more remaining characters
  if (k == 0)
  {
    sub[curr] = '\0';
    cs1010_println_string(sub);
    return;
  }
  // Iterate through all the possible characters we can choose
  for (size_t i = 0; i <= len - k; i += 1)
  {
    sub[curr] = src[i];
    print_sub(src + i + 1, len - i - 1, k - 1, curr + 1, sub);
  }
}

So, for this question, during every iteration, the possible characters we can choose are from 0 to len-k in the current src string! And once we have added a character to our sub string, we move our src string to the remaining string behind that character.

Whne you allocate the memory for char *sub, remember to add 1 to k since a string must end with \0. That is also why you need to add \0 in the base case in the code above.

Tips

  1. Somtimes changing the loop condition will change the obvious time complexity, pay attention to the "hidden" time complexity and sometimes this kind of change can be utilised to make your code more effificient.

  2. When you want to improve the complexity of searching/sorting problems, try thinking about how to narrow your "searching area". This will be very useful!

  3. Include my solution and prof's solution to 5. Substring* in PE2 Review.

This is actually a variant of from PE2 (AY22/23)

3. Group*
94KB
pe2-2021-s1.pdf
pdf
Questions
158KB
pe2-2021-s1-with-comments.pdf
pdf
Official Answers