Skip to content

CS 31 (Fall '16)

Daniel Norman edited this page Jun 5, 2017 · 1 revision

convertStringToInt

Contributed by Katie Luangkote.

This function takes as input a C-string containing a number and the number of characters in the array (not including 0 byte). It outputs an integer representation of that number.

Example

Input: char number[] = [1, 2, 3, 4]; Return: 1234

int convertStringToInt(char number[], int len) {
  int rtrn = 0;
  int multiplier = 1;
  for (int i = len-1; i >= 0; i--) {
    rtrn += (number[i]-'0')*multiplier;
    multiplier *= 10;
  }
  return rtrn;
}

Multi-character Palindromes

Contributed by Rahul Salvi.

Most palindromes consider only one character at a time. A common example would be 'racecar'. Checking if a word is a palindrome like this is quite easy -- just check that the first character matches the last, the second character matches the second-to-last, and so on. However, lets define a palindrome to have an order, which is the number of characters to compare in a block. For example, 'racecar' has an order of 1. On the other hand, 'abcdcdab' is a palindrome of order 2, since the first 'ab' matches the 'ab' at the end, and the first 'cd' can be matched against the second 'cd'. For this problem, create a function isPalindrome that takes three arguments in order: an input string (const char*), the length of the string (int), and the order to check (int). isPalindrome should return true if the input string is a palindrome of the correct order, and false if it is not. You may assume that the string length will always be a multiple of the order.

Example

'a' is a palindrome of order 1

'abcddcba' is a palindrome of order 1

'xyzabcxyz' is a palindrome of order 3

'hello world world hello ' is a palindrome of order 6 (be careful about the trailing space)

'' (an empty string) is a palindrome of any order

Solution

The only really tricky part of this question is determining the right array indices to check against each other. We can split the string into blocks of size 'order'. From there, we compare blocks at the beginning to blocks at the end. If any comparisons fail, we know the string is not a palindrome.

bool isPalindrome(const char* str, int len, int order) {
    int blocks = ((len / order) / 2);
    for (int i = 0; i < blocks; i++) {
        for (int j = 0; j < order; j++) {
            int index1 = ((i * order) + j);
            int index2 = (len - ((i + 1) * order)) + j;
            if (str[index1] != str[index2]) {
                return false;
            }
        }
    }
    return true;
}

Constructing A Multiplication Table

Contributed by Frank Fu.

Write a void function called multiplicationTable that takes two int arguments, rowMax and columnMax, in order to print out a rowMax by columnMax multiplication table. Output an error message instead of the table when either rowMax or columnMax that the user entered is negative. In addition, if rowMax or columnMax exceeds 9, set them to 9 and print out the table as if the user entered 9 as an input instead of the larger value. Make sure each column is separated by a tab, and each row starts at a new line. Also, be sure to write a main function that prompts the user to enter the number of rows (rowMax) and the number of columns (columnMax) before calling the multiplicationTable function in the main function to produce the output.

Example

Example 1:

Please enter the number of rows: 9
Please enter the number of columns: 9
1*1=1   2*1=2   3*1=3   4*1=4   5*1=5   6*1=6   7*1=7   8*1=8   9*1=9
1*2=2   2*2=4   3*2=6   4*2=8   5*2=10  6*2=12  7*2=14  8*2=16  9*2=18
1*3=3   2*3=6   3*3=9   4*3=12  5*3=15  6*3=18  7*3=21  8*3=24  9*3=27
1*4=4   2*4=8   3*4=12  4*4=16  5*4=20  6*4=24  7*4=28  8*4=32  9*4=36
1*5=5   2*5=10  3*5=15  4*5=20  5*5=25  6*5=30  7*5=35  8*5=40  9*5=45
1*6=6   2*6=12  3*6=18  4*6=24  5*6=30  6*6=36  7*6=42  8*6=48  9*6=54
1*7=7   2*7=14  3*7=21  4*7=28  5*7=35  6*7=42  7*7=49  8*7=56  9*7=63
1*8=8   2*8=16  3*8=24  4*8=32  5*8=40  6*8=48  7*8=56  8*8=64  9*8=72
1*9=9   2*9=18  3*9=27  4*9=36  5*9=45  6*9=54  7*9=63  8*9=72  9*9=81

Example 2:

Please enter the number of rows: 7
Please enter the number of columns: 10
Sorry, the maximum number of columns we can have is 9! (Note: This line/output is optional.)
1*1=1   2*1=2   3*1=3   4*1=4   5*1=5   6*1=6   7*1=7   8*1=8   9*1=9
1*2=2   2*2=4   3*2=6   4*2=8   5*2=10  6*2=12  7*2=14  8*2=16  9*2=18
1*3=3   2*3=6   3*3=9   4*3=12  5*3=15  6*3=18  7*3=21  8*3=24  9*3=27
1*4=4   2*4=8   3*4=12  4*4=16  5*4=20  6*4=24  7*4=28  8*4=32  9*4=36
1*5=5   2*5=10  3*5=15  4*5=20  5*5=25  6*5=30  7*5=35  8*5=40  9*5=45
1*6=6   2*6=12  3*6=18  4*6=24  5*6=30  6*6=36  7*6=42  8*6=48  9*6=54
1*7=7   2*7=14  3*7=21  4*7=28  5*7=35  6*7=42  7*7=49  8*7=56  9*7=63

Example 3:

Please enter the number of rows: 0
Please enter the number of columns: 0
(Note: There is no output in this case!)

Example 4:

Please enter the number of rows: -2
Please enter the number of columns: 1
ERROR! We can't have negative rows or negative columns!

Solution

#include <iostream> 

using namespace std;

void multiplicationTable(int rowMax, int columnMax) {
  int i, j;
  if (rowMax < 0 || columnMax < 0) {
      cout << "ERROR! We can't have negative rows or negative columns! \n";
      return;
      }

  if (rowMax > 9) {
      cout << "Sorry, the maximum number of rows we can have is 9! \n";
      rowMax = 9;
      }

  if (columnMax > 9) {
      cout << "Sorry, the maximum number of columns we can have is 9! \n";
      columnMax = 9;
      }

  for (i = 1; i <= rowMax; i++) {
      for (j = 1; j <= columnMax; j++)
          cout << j << "*" << i << "=" << j*i << "\t";
      cout << "\n";
      }
}

int main() {
  int r, c;
  cout << "Please enter the number of rows: ";
  cin >> r;
  cout << "Please enter the number of columns: ";
  cin >> c;
  multiplicationTable(r, c);
  return 0;
}

Unique Prime Numbers

Contributed by Jason Yee.

Write a function, countUniquePrimes, that accepts both an array of ints and the size of said array and returns the number of UNIQUE prime numbers in that array. You may assume that the passed size does not exceed the actual size of the array. Should, however, the parameters passed to the function be nonsensical (e.g. a negative integer passed for the array size) the function should return -1. It is recommended that you write two helper functions for this problem.

/*We'll declare the headers of these helper functions ahead of time so we can use
them now, and implement them for real afterward.
Writing the helper functions before the function of countUniquePrimes is
acceptable as well.*/
bool hasAppearedBefore(int*, int);
bool isPrime(int);

int countUniquePrimes(int* numList, int size) {
    if (numList == nullptr || size < 0) /*Catch nonsensical parameters*/
        return -1;
  
    int numPrimes = 0;
    for (int i = 0; i < size; i++) {
      	/*Two conditions: hasn't been seen before in the list,
        and is prime. Each time we meet a number that meets those
        conditions, increment numPrimes as a counter.
        We'll use the helper functions above to make this code clean.*/
        if (hasAppearedBefore(numList, i) == false && isPrime(numList[i]) == true) {
          numPrimes++;
        }
    }
    return numPrimes;
}

/*Given pointer to stary of array of ints and an index in that array,
returns true if element at passed index appears at any previous indeces
i.e. is a repeat and not unique*/
bool hasAppearedBefore(int* numList, int index) {
    int number = numList[index];
    for (int j = 0; j < index; j++) { /*All indeces that come before index i*/
        if (numList[j] == number) /*Has appeared before in the list*/
            return true;
    }
  
    /*No duplicates found in previous indeces*/
    return false;
}

/*Given a positive integer, returns if it is prime.*/
bool isPrime(int num) {
    for (int j = 2; j < num; j++) { /*For all possible primes under num*/
        if (num % j == 0) /*Found a divisor for num*/
            return false;
    }
    
    /*No divisors found*/
    return true;
}

Converting a string to an int

Contributed by Ryan Lo.

Your job is to write a function called toInt() that takes a string containing only numerical characters as input and returns an integer of the actual number the string represents

For instance: toInt("123") should return the integer: 123

#include <iostream>
using namespace std;
#include <string>
#include <cassert>

int toInt(string s) {
    int res = 0;
    int size = s.size();
    for (int i = 0; i < size; i ++) {
        res = res * 10 + (s[i] - '0');
    }
    return res;
}

int main() {
    /*Write a function called "toInt" that converts a string consisting of only numerical 
     characters to an integer and returns the result.
     For instance: toInt("123") should return the integer: 123
     */
    
    assert(toInt("123") == 123);
    assert(toInt("921340") == 921340);
    cout << "All cases worked!" << endl;
}

Pointer Palooza

Contributed by John Stucky.

What is the output of the following code?

#include <iostream>
using namespace std;
int main() {
    int a[10];
    int* b = a;
    *a = 5;
    *(a+1)=(*a)+1;
    cout << (*(++b))+(*(b--)) << endl;

    char s[5] = { 'C', 'S', '3', '1', '\0' }; 
    char* t = &s[s[3]-'0'];
    t[*(t+1)-'1'] = '\0';
    cout << s << endl;

    int x[5] = { 1, 2, 3, 4, 5 }; 
    int* y[5];
    for (int i = 0; i < 5; i++) {
        y[4-i]= &x[i];
    }
    y[2]--;
    x[2]++;
    (*y[x[1]])--;
    for (int i = 0; i < 5; i++) {
        cout << x[i];
    }
    cout << endl;  
}

Solution

The code outputs

12
CS3
11445

For the first output, a is initialized to be an array of size 10. In the next line, b is an integer pointer pointing at the first index of a. The line *a = 5 sets a[0] = 5. *(a+1) = (*a)+1 is equivalent to a[1]=a[0]+1, so a[1] now equals 6. b is currently pointing to the contents at a[0], so pre-incrementing it before dereferencing it returns the contents at a[1], a value of 6. Note that *(b--) also returns the contests at a[1], so the printed statement is equivalent to a[1]+a[1], or 6+6, so 12 is printed.

For the second output, s is a pointer to a character array of size 5. Recall that characters in C++ are represented by integers, and that the integers used for the integer characters (e.g., '0', '1') are consecutive. This means that s[3]-'0' equals '1'-'0', equals 1. t is assigned to &s[s[3]-'0'], or '&s[1]', so t is a pointer to the contents of s[1]. In the assignment t[*(t+1)-'1']='\0', *(t+1) refers to t[1] or equivalently s[2], with contents of '3'. *(t+1)-'1' is '3'-'1' is 2, so t[2] is assigned the null character '\0'. When the c-string s is printed, characters up until the first \0 are printed, so the resulting printout is CS3.

For the third printout, without loss of generality, imagine that array x is stored starting at memory address 1000 and let the size of an int be 4. Then the array of int pointers y will have values 1016, 1012, 1008, 1004, 1000.

|index| 0  | 1  | 2  | 3  | 4  |
|-----|----|----|----|----|----|
|  x  | 1  | 2  | 3  | 4  | 5  |
|  y  |1016|1012|1008|1004|1000|

y[2]-- will update y[2] to 1004 (remember that in pointer arithmetic, pointers are increased or decreased by the size of the object to which they point). x[2]++ will increment the contents of x[2] to 4. Going into the next line of code, the array contents are:

|index| 0  | 1  | 2  | 3  | 4  |
|-----|----|----|----|----|----|
|  x  | 1  | 2  | 4  | 4  | 5  |
|  y  |1016|1012|1004|1004|1000|

y[x[1]] is easy to determine from the above table. x[1] is 2, so y[x[1]] is y[2] is 1004, the address where x[1] is stored. When this address is dereferenced and decremented, x[1] is updated to 1. The final printout is therefore 11445.


Code Tracing: Loops & Arrays

Contributed by Stephanie Lam.

Find the output produced by this code.

#include <iostream>
using namespace std; 

int main() {
    int arr[5] = {9, 3, 1, 7, 2}; 

    int n = 3;
    while (n >= 0) {
        arr[n] += (n * n);
        --n; 
    }

    while (n < 4)
        ++n; 

    cout << n << endl; 

    for (int i = 0; i < 5; i++)
        cout << arr[i] + n << "" ""; 
    cout << endl; 

    return 0;
}

Solution

Output:

4
13 8 9 20 6

Duplicate Elements

Contributed by Yiyin Jin.

Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. Do not allocate extra space for another array, you must do this in place with constant memory.

Example

Given input array nums = [1,1,2], Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length.

Solution

Since the array is already sorted, we can keep two pointers i and j, where i is the slow-runner while j is the fast-runner. As long as nums[i] = nums[j], we increment j to skip the duplicate. When we encounter nums[j]≠nums[i], the duplicate run has ended so we must copy its value to nums[i+1]. ii is then incremented and we repeat the same process again until j reaches the end of array.

public int removeDuplicates(int[] nums) {
  if (nums.length == 0) return 0;
  int i = 0;
  for (int j = 1; j < nums.length; j++) {
    if (nums[j] != nums[i]) {
      i++;
      nums[i] = nums[j];
    }
  }
  return i + 1;
}

Reverse Recursively

Contributed by Jason Wong.

Warm up to main problem: Write a function to reverse a string; can you do this without creating a new string?

Main problem: Write a recursive function to reverse a string. This recursive function must only take a single parameter, the string that is to be reversed. No global variables allowed.

Function skeletons below:

// Warm up
string reverse(string s) {
}

// Main problem
string reverseRecursive(string s) {
}

Solution

#include <string>
using namespace std;

string reverse(string s) {
    // Pay attention to where we must stop.
    // Verify that s.size()/2 works for both even and odd lengths
    for (int i = 0; i < s.size() / 2; i++) {
        // Compute index from end of string
        int lastIndex = s.size() - 1 - i;
        
        // Swap
        char tmp = s[lastIndex];
        s[lastIndex] = s[i];
        s[i] = tmp;
    }
    return s;
}

string reverseRecursive(string s) {
    // Base case: an empty string, or a string of size 1 is already "reversed"
    if (s.size() == 0 || s.size() == 1) {
        return s;
    }
    
    // Our reversed string is formed by the following:
    // last character
    // reversed version of string without first and last character
    // first character
    return s[s.size() - 1] + reverseRecursive(s.substr(1, s.size() - 2)) + s[0];
}

Is Substring

Contributed by Jennifer Tan.

Write a function, isSubstring, that takes in two strings and returns true if one string is an exact substring (capitalization counts) of the other. The empty string is always a substring of another string.

Example

input 1: 'apple', 'pineapple'
output 1: true
input 2: 'pineapple', 'Apple'
output2: false

Solution

#include <string>
using namespace::std;

bool isSubstring(string a, string b) {
    string shorter = a;
    string longer = b;
    if (a.length() > b.length()) {
        shorter = b;
        longer = a;
    }
    
    if (shorter == "")
        return true;
    
    int i = 0;
    while (i < longer.length() && (i + shorter.length()) <= longer.length()) {
        if (longer[i] == shorter[0]) {
            int l_i = i + 1;
            int s_i = 1;
            bool foundSubString = true;
            while (l_i < longer.length() && s_i < shorter.length()) {
                if (longer[l_i] != shorter[s_i]) {
                    foundSubString = false;
                    break;
                }
                l_i++;
                s_i++;
            }
            if (foundSubString == true) {
                return true;
            }
        }
        i++;
    }
    return false;
}

Integer to Binary Conversion

Contributed by Chaoran Lin.

Write a function that takes a positive integer and converts it to its binary representation.

Examples

Input: 2 Output: 10 Input: 5 Output: 101 Input: 10 Output: 1010

Solution

The solution is to convert int to binary by dividing num until it reaches 0, and multiplying the remainder of every division by an incrementing exponent of 10, and then return the sum of those multiplication results.

#include <iostream>
#include <math.h>

using namespace std;

/**
* FUNCTION SIGNATURE: int convert(int num)
 * PURPOSE: convert int to binary by dividing num until it reaches 0, and multiplying the remainder of every division
 * by an incrementing exponent of 10, and then return the sum of those multiplication results.
 * PARAMETER:
 *     num, the user-inputed integer
 * RETURN VALUE:
 *     num converted to a binary
*/

int convert(int num) {
    int binary = 0;
    int remainder = 0;
    int i = 0;
    while (num != 0) {
        remainder = num % 2;
        num = num / 2;
        binary += (remainder * pow(10.0, i));
        i++;
    }

    return binary;
}


Increment Digits

Contributed by Neda Vesselinova.

Given a three digit number, increment each of its digits and return the resulting number.

Example

incrementDigits(123) should return 234. incrementDigits(906) should return 1017.

Solution

To get the hundreds component, subtract the number in the tens and ones places from the number. To get the tens component, subtract the number in the ones place from the number in the tens and ones place. To get the ones component, get the number in the ones place. To increment the digits, add 100 to the hundreds, 10 to the tens, and 1 to the ones. Add each of the components to get the resulting number.

int incrementDigits(int num) {
    int hundreds = num - (num % 100);
    int tens = (num % 100) - (num % 10);
    int ones = num % 10;

    hundreds += 100;
    tens += 10;
    ones += 1;

    return hundreds + tens + ones;
}

Zig-Zag Sequence

Contributed by Omar Ozgur.

Write a function zigZagSequence that takes an array of integers and its length, and tells if the array is in "zig-zag" form, such that n1 < n2 > n3 < n4 etc.

Example

int b[6] = {1, 3, -5, 4, 1, 0};
zigZagSequence(b, 5) => true
zigZagSequence(b, 6) => false

Solution

#include <cassert>

bool zigZagSequence(int seq[], int n) {
  for (int i = 1; i < n; i++) {
    if (i % 2 == 1) {
      if (seq[i] <= seq[i - 1])
        return false;
    } else {
      if (seq[i] >= seq[i - 1])
        return false;
    }
  }
  return true;
}

int main() {
  int a[0] = {};
  int b[6] = {1, 3, -5, 4, 1, 0};
  int c[4] = {3, 2, 4, 1};
  assert(zigZagSequence(a, 0) == true);
  assert(zigZagSequence(b, 5) == true);
  assert(zigZagSequence(b, 6) == false);
  assert(zigZagSequence(c, 4) == false);
}

Pyramid of Money

Contributed by Matthew Wong.

Write a function that prints a pyramid of $'s. The function should take a single integer parameter n to determine the size of the pyramid. Also, the pyramid should be right-aligned, so you will need to print spaces to correctly align the $'s.

Example

For example, if the function was called with n = 3, the output would be:

  $
 $$
$$$

If it was called with n = 5, the output would be:

    $
   $$
  $$$
 $$$$
$$$$$

Solution

We are going to use a loop to print out the rows of the pyramid. Each iteration of this loop will print a single row. Within the loop will be two nested loops that will be responsible for printing the spaces and $'s of each row.

#include <iostream>
using namespace std;

void pyramidOfMoney(int n) {
    // there will be n rows in the pyramid
    // the nth row will have n dollar signs
    for (int i = 1; i <= n; i++) {
        // print the spaces preceding the dollar signs
        for (int spaces = 0; spaces < n - i; spaces++)
            cout << "" "";
        
        // print the dollar signs for the row
        for (int money = 0; money < i; money++)
            cout << ""$"";
        
        cout << endl;
    }
}

Counting Array Duplicates

Contributed by Jason Xu.

Given a sorted 2D array of integers (ascending left to right, top to bottom), write a function that returns the number of integers in the array that appear more than once. Width and height of array will also be given as parameters.

Example

Input: nums = { {1, 1, 2, 3}, {3, 3, 100, 100}, {101, 101, 102, 103} } (height = 3, width = 4)

Output: func(nums, height, width) = 4

Solution

//
//  testing.cpp
//  for CS31
//

int countDups(int ** arr, int height, int width) {
  if (width < 1 || height < 1)
    return 0;
  
  int last = 0;
  if (arr[0][0] == 0)
    last = -1;
  int count  = 0;
  bool onDup = false;
  for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
      if (arr[i][j] == last) {
        if (!onDup) {
          count++;
          onDup = true;
        }
      } else {
        last = arr[i][j];
        onDup = false;
      }
    }
  }
  return count;
}

Rotate string s to the right k times

Contributed by Yi Peng

Example

rotate("abcde",1) returns "eabcd". rotate("abcde",2) returns "deabc". rotate("abcde",3) returns "cdeab".

Solution

#include <iostream>
using namespace std;

string rotate(string s, int k) {
if (k < 0 || s.empty()) {
     return s;
}
int toRotate = k % s.size();
return s.substr(s.size() - toRotate) + s.substr(0, s.size() - toRotate);
}

Predict the output

Contributed by Bowei Wang.

Given the following code, predict the output.

void mystery(int *a, int b, int *c) {
    a = b + c;
    b = a + c;
    c = a + b;
}
int main() {
    int a, b, c;
    a = 1;
    b = 2;
    c = 3;
    mystery(b, c, a);
    cout << a << "" "" << b << "" "" << c << endl;
}

Solution

After calling mystery: In main: a:1 b:2 c:3 In mystery: &a:b b:3 &c:a

After the line: a = b + c; In main: a:1 b:4 c:3 In mystery: &a:b b:3 &c:a

After the line: b = a + c; In main: a:1 b:4 c:3 In mystery: &a:b b:5 &c:a

After the line: c = a + b; In main: a:9 b:4 c:3 In mystery: &a:b b:5 &c:a

After mystery returns: In main: a:9 b:4 c:3

Output: 9 4 3


People Problems

Contributed by Jeffrey Jiang.

Consider the following code:

#include <string>

using namespace std;

class Name {
  public:
    Name(string first, string last) {
        m_first = first;
	    m_last = last;
    }
  private:
    string m_first;
    string m_last;
}

class Person {
  public:
    Person(string first, string last, int age, Person best_friend) {
        m_name(first, last);
	    m_age = age;
	    m_bestie = best_friend;
    }
  private:
    Name m_name;
    int m_age;
    Person m_bestie;
}

a. Does this code compile? If not, change the code so that it does compile.

b. Let's say that John Smith, who is age 20, has David Smallberg as his best friend, and Person a contains John Smith's information. Write the code that can retrieve the first name of David Smallberg's best friend, assuming that everything is defined (nothing null or missing) and all fields are made public.

c. Does Person need a non-default destructor to avoid memory leaks?

Solution

a. Here is the full code that is required to have it compile. Of course there are a couple different ways you can write it.

#include <string>

using namespace std;

class Name {
  public: 
    Name(string first, string last) {
        m_first = first;
        m_last = last;
    }
  private: 
    string m_first; 
    string m_last; 
};

class Person {
 public: 
    Person(string first, string last, int age, Person* best_friend)
    : m_name(first, last), m_age(age), m_bestie(best_friend) {}
 private:
    Name m_name;
    int m_age; 
    Person* m_bestie; 
};

a. List of errors in the problem code: 1. Missing semicolons at the end of the class declaration. 2. Since Name has no default constructor, we must have m_name defined in a initializer list. 3. Person cannot be a member of its own definition. However, we can have a pointer to Person declared.

b. ((a.m_bestie)->m_bestie)->m_first

c. No. Since no pointer is dynamically allocated in Person, but only passed, there is no need to destruct this class by deleting a pointer. One additional point to bring up is that given this strict definition, there must be one Person with NULL as a best friend, since we don't have a way of setting it after construction.


stoi

Contributed by Prathyush Katukojwala.

String str contains an integer in string form. Convert it to an integer without using the standard library stoi or any equivalent library function.

Example

int out = stoi("150");
// out will contain the integer 150

Solution

// str contains only an integer in string form and nothing else
int stoi(string str) {
    int num = 0;
    for (int i = 0; i < str.size(); i++) {
        num *= 10;  // shift all digits to the left one place
        num += str[i] - '0';  // add the latest number
    }
    return num;
}

Longest Repeating Substring

Contributed by Christian Warloe.

Write a function that takes a string argument and returns the length of the longest substring with repeating characters.

Example

The string "abcdef" should return 1. The string "abbccdef" should return 2. The string "aaabbcdeff" should return 3. The string "abbbcccdddd" should return 4.

Solution

int longest_repeating_substr(string mystr) {
    int currlen = 1;
    int maxlen = 0;
    if (mystr.size() < 1) {
        return 0;
    }
    char curr = mystr[0];
    for (int i = 1; i < mystr.size(); i++) {
        if (mystr[i] == curr) {
            currlen++;
        } 
        else {
            if (currlen > maxlen)
                maxlen = currlen;
            currlen = 1;
            curr = mystr[i];
        }
    }
    return maxlen;
}

String Rotation

Contributed by Hongyi Zhang.

Given a string, rotate the string to the right by k steps (e.g., ("abc", 1)"cab"). Think of a solution to do this without using an additional array!

Example

("abcdef", 3) -> ("defabc")
("defabc", 6) -> ("defabc")
("defabc", 1) -> ("efabcd")
("efabcd", 5) -> ("defabc")

Solution

#include <iostream>
#include <string>
#include <algorithm>
#include <assert.h>

using namespace std;

// using O(n) additional space
void rotateString(string* str, int k) {
    string shift = """";
    // temporarily store values to be shifted
    int ka = k % str->size();
    for (int i = 0; i < ka; i++) {
        shift += (*str)[i];
    }

    // rotate the rest of the string
    for (int i = 0; i < str->size() - ka; i++) {
        (*str)[i] = (*str)[i + ka];
    }

    // append our stored values
    for (int i = 0; i < shift.size(); i++) {
        (*str)[str->size() - ka + i] = shift[i];
    }
}

// How about doing this in place? :)
void rotateStringInPlace(string* str, int k) {
    // str.begin() is a pointer to the first element
    // str.end() is a pointer to the first element past the last element (i.e. str[str.size()])
    // This is just how the C++ standard library works!
    // Try implementing your own reverse function - `reverse(string& str, int start, int end)`
    int ka = k % str->length();
    // flip the entire string
    // abcd -> dcba
    reverse(str->begin(), str->end());
    // flip the last k characters
    // dcba -> dcab
    reverse(str->end() - ka, str->end());
    // flip the rest of the string
    // dcab -> cdab
    reverse(str->begin(), str->end() - ka);
    // think about why this works! :)
}

int main() {
    string test = "abcdef";
    rotateString(&test, 3);
    assert(test == "defabc");
    rotateString(&test, 6);
    assert(test == "defabc");
    rotateString(&test, 1);
    assert(test == "efabcd");
    rotateString(&test, 5);
    assert(test == "defabc");
    test = "abcdef";
    rotateStringInPlace(&test, 3);
    assert(test == "defabc");
    rotateStringInPlace(&test, 6);
    assert(test == "defabc");
    rotateStringInPlace(&test, 1);
    assert(test == "efabcd");
    rotateStringInPlace(&test, 5);
    assert(test == "defabc");
}

sumOfIndexes

Contributed by Jeffrey Chan.

Implement a function called sumOfIndexes that takes in an array of integers and the size of the array, and returns the sum of the indexes of the first two integers within the array that are equivalent. If there are no equivalent integers, return -1. You do not have to worry about being passed any invalid arguments such as a negative size argument.

Function signature: int sumOfIndexes(int arr[], int size)

Example

int nums[5] = {1, 2, 3, 3, 2};
int x = sumOfIndexes(nums, 5);
// x = 5 because nums[1] = 2, nums[4] = 2,
// therefore 1 + 4 = 5

Solution

#include <iostream>
using namespace std;

int sumOfIndexes(int arr[], int size) {
    for (int k = 0; k < size; k++) {
        for (int j = k + 1; j < size; j++) {
            if (arr[k] == arr[j])
                return k + j;
        }
    }
    return -1;
}

Reversing an Integer

Contributed by Jeremiah Fan.

Given an integer, write a function that prints out its digits in reverse order. Make sure that negative signs are preserved.

Function signature: void printReverse(int num);

Example

printReverse(500)  -> 005
printReverse(-436) -> -634
printReverse(0)	   -> 0
printReverse(0010) -> 01

Solution

#include <iostream>
using namespace std;

void printReverse(int num) {
    if (num == 0) {
        cout << num << endl;
        return;
    }

    if (num < 0) {
        cout << ""-"";
        num *= -1;
    }

    while (num > 0) {
        cout << num % 10;
        num /= 10;
    }
    cout << endl;
}

Roman Numerals to Integer

Contributed by Adam Romayor.

Write a function romanToInt that takes a single string of roman numerals as input and returns the corresponding integer value. If the input is invalid return -1.

Roman Numerals and their values: I = 1 V = 5 X = 10 L = 50 C = 100 D = 500 M = 1000

Function signature: int romanToInt (string s);

Example

romanToInt("X")        -> 1
romanToInt("IV")       -> 4
romanToInt("LDDMXIII") -> 963
romantToInt("wrong")   -> -1

Solution

This solution maintains the value of the previous Roman Numeral. That way, if the previous roman numeral is less than the current one, subtract off 2*prev. We multiply prev by 2 before subtracting, since we have already added the previous roman numeral and must account for that.

int romanToInt(string s) {
	int sum = 0;
	int prev = 0;
	for (int i = 0; i < size; i++) {
		switch (s[i]) {
		case 'M':
			sum += 1000;
			if (prev < 1000)
				sum -= 2*prev;
			prev = 1000;
			break;
		case 'D':
			sum += 500;
			if (prev < 500)
				sum -= 2*prev;
			prev = 500;
			break;
		case 'C':
			sum += 100;
			if (prev < 100)
				sum -= 2*prev;
			prev = 100;
			break;
		case 'L':
			sum += 50;
			if (prev < 50)
				sum -= 2*prev;
			prev = 50;
			break;
		case 'X':
			sum += 10;
			if (prev < 10)
				sum -= 2*prev;
			prev = 10;
			break;
		case 'V':
			sum += 5;
			if (prev < 5)
				sum -= 2*prev;
			prev = 5;
			break;
		case 'I':
			sum += 1;
			prev = 1;
			break;
		default:
			return -1;
		}
	}
	return sum;
}

Array Ordering.

Contributed by Ramya Satish.

Given an array, return whether the array is sorted in ascending order and update the values at the pointers pointing to the min and max. You may assume that the array will not be of a size less than or equal to zero, and that min and max are not null pointers.

Solution

bool inOrder(int arr[], int size, int  *min, int *max) {
    int tempMin = arr[0];
    int tempMax = arr[0];
    bool order = true;
    for (int i = 1; i < size; i++) {
        if (arr[i] < tempMin) {
            tempMin = arr[i];
        }
        if (arr[i] > tempMax) {
            tempMax = arr[i];
        }
        if (arr[i] < arr[i - 1]) {
            order = false;
        }
    }
    *min = tempMin;
    *max = tempMax;
    return order;
}

What is Mystery?

Contributed by Alex Wu.

What does the following code output? What is the functionality of mystery (what does it return, given n)?

#include <iostream>
using namespace std;

int mystery(int n) {
    if (n == 1)
        return 0;
    return 1 + mystery(n / 2);
}

int main() {
    cout << mystery(5) << endl;
    cout << mystery(10) << endl;
    cout << mystery(100) << endl;
}

Solution

The correct output is as follows: 2 3 6

Mystery returns log2(n) rounded down to the nearest integer.


Password Strength Checker

Contributed by: Matt Fabius

Create a program that checks the strength of a user entered password. If the password contains a letter, a digit, and a special character and is longer than 8 characters, it is considered strong.

Bonus: Take in a username and verify that the password doesn't contain the username as well.

Example

A good password: MargaretThatcheris110%cool

Solution

#include <iostream>
#include <string>
using namespace std;

/*
    Create a password checker that outputs whether or not your password is good.
 */
    
int main() {
    bool containsDigit = false;
    bool containsLetter = false;
    bool containsSpecial = false;
    string password;
    getline(cin, password);
    
    for (int i = 0; i < password.length(); i++) {
        if (isalpha(password[i]))
            containsLetter = true;
        else if (isdigit(password[i]))
            containsDigit = true;
        else
            containsSpecial = true;
    }
    
    if (containsDigit && containsLetter && containsSpecial && password.length() > 8)
        cout << "Good password" <<endl;
}

Trimming whitespace

Contributed by Michael Li.

Given a C string, replace multiple consecutive whitespace characters with only one space character. Also, delete leading and ending whitespace. Do this in-place—i.e., don't use an extra array.

Example

If the input is " Hello world, it's C++! ", the array should be changed to "Hello world, it's C++!".

Solution

Keep a pointer to the front and a pointer to the current character that needs to be moved if there's extra whitespace. To determine if there's extra whitespace, count the number of consecutive space characters and see if it's greater than 1 if it's in the middle; if it's at the start of the string, all whitespace is extra. If there's extra whitespace, copy characters to earlier in the array.

void trim(char* s) {
    char* front = s;
    unsigned spaceCount = 0, charCount = 0;
    bool totalExtraSpaces = false;
    while (true) {
        while (*s == ' ') {
            spaceCount++;
            s++;
        }
        totalExtraSpaces = totalExtraSpaces || (charCount != 0 ? spaceCount - 1 : spaceCount);
        if (*s == '\0') {
            front[charCount] = '\0';
            return;
        }
        if (charCount != 0) {
            front[charCount] = ' ';
            charCount++;
        }
        while (*s != ' ') {
            if (totalExtraSpaces) {
                front[charCount] = *s;
            }
            charCount++;
            if (*s == '\0') {
                return;
            }
            s++;
        }
        spaceCount = 0;
    }
}

Searching a Sorted and Rotated Array

Contributed by Aniqa Kamal.

Write a function to find an element in a sorted array that has been rotated by some integer value. Return the index of the element and -1 if the element is not in the array.

Example

Input: arr = [3, 5, 6, 0, 2], key = 0 Output: 3

Solution

int findPivot(int arr[], int start, int end) {
    if (start == end)
        return start;
    if (start > end)
        return -1;
    int mid = (start + end) / 2;
    if (mid < end && arr[mid] > arr[mid+1])
        return mid;
    if (mid > start && arr[mid] < arr[mid-1])
        return mid-1;
    if (arr[start] >= arr[mid])
        return findPivot(arr, start, mid-1);
    return findPivot(arr, mid+1, end);
}

int binarySearch(int arr[], int start, int end, int key) {
    if (start > end)
        return -1;
    int mid = (end + start) / 2;
    if (arr[mid] == key)
        return mid;
    if (arr[mid] > key)
        return binarySearch(arr, start, mid-1, key);
    return binarySearch(arr, mid+1, end, key);
}

int pivotedBinarySearch(int arr[], int n, int key) {
    int pivot = findPivot(arr, 0, n-1);
    if (pivot == -1)
        return binarySearch(arr, 0, n-1, key);
    if (arr[pivot] == key)
        return pivot;
    if (arr[0] <= key)
        return binarySearch(arr, 0, pivot-1, key);
    return binarySearch(arr, pivot+1, n-1, key);
}

struct Node {
    int val;
    Node* left, *right;
};

// Find the lowest common ancestor to two nodes in a binary tree. 
Node* findLowestCommonAncestor(Node* root, Node* a, Node* b) {
    if (!root || !a || !b)
        return nullptr;
    if (a->val == root->val || b->val == root->val)
        return root;
    Node* left = findLowestCommonAncestor(root->left, a, b);
    Node* right = findLowestCommonAncestor(root->right, a, b);

    if (left && right)
        return root;
    else if (left)
        return left;
    return right;
}

Fun with functions and references

Contributed by Aditya Padmakumar.

What is the output of the following program?

#include <iostream>
using namespace std;

int x = 5;

int &f() {
    return x;
}

int main() {
    f() = 10;
    cout << x;
}

A. 5 B. Address of ‘x’ C. Compile error D. 10 E. None of the above

Solution

D. f returns a reference, hence it can appear on the left hand side of the assignment operator.


IsAlternation

Contributed by Brendon Daugherty.

Without creating any local variables, and only iterating over the array once, write a function is_alternation that has the following signature, taking two char* pointers as parameters and returning a bool value. The function is_alternation should return true if and only if the given c-string alternates between two characters. Iterate through the c-string using only pointers, without using array index access syntax ([ ]).

bool is_alternation(char* startOfWord, char* endOfWord);

You may assume that all C strings end in the null byte /0, and that startOfWord and endOfWord do in fact exist, and also point to the same string of interest.

Example

The following code should output the string “All Good Fam”, without any errors.

int main()
{
    char h[6] = "H";
    char haha[5] = "haha";
    char hahah[6] = "hahah";
    char ha[3] = "ha";
  
    assert(is_alternation(haha, haha+5));
    assert(is_alternation(hahah, hahah + 6));
    assert(is_alternation(ha, ha + 3));
    assert(!is_alternation(h, h + 1));
    
    std::cout << "All Good Fam" << std::endl;
}

Solution

bool is_alternation(char *startOfWord, char* endOfWord) {
    // This protects against null pointers
    if ( !startOfWord || !endOfWord )
        return false;
        
    // You can use pointer arithmetic to get the size of your word!
    if ( endOfWord - startOfWord < 2 ) {
            return false;
        }
    
    // Because we no longer need the pointer to the end of the word, we can use endOfWord
    // to iterate through our string!
    endOfWord = startOfWord;
        
    // All c-strings end in the nullbyte
    while ( *endOfWord != '\0' ) {
            // If the current char we look at is 
            // odd, check to see if it is the same as the second letter of
            // the string
            if ( ( (endOfWord - startOfWord) % 2 ) && *endOfWord != *(startOfWord + 1) )
            return false;
                
            // If the current char we look at is even,
            // check to see if it is the same as the first letter of
            // the string
            else if ( (!(endOfWord - startOfWord) %2) && *endOfWord != *(startOfWord) )
            return false;     
            // Don't forget to increment!
            endOfWord += 1;
        }
    // Return true, if none of our tests came back false.
    return true;
}

Function Overload Practice

Contributed by Tyler Carson.

Using what you know about overloaded functions, interpret function main() below. Transcribe what is printed to the console by main().

#include <iostream>

int foo() {
    std::cout << "foo: void" << std::endl; 
    return 3;
}

int foo(int x) {
    if (x < 0) {
        std::cout << "foo: " << x << " squared" << std::endl;
        return x*x;
    } else {
        std::cout << "foo: " << x << " + 1" << std::endl;
        return x+1;
    }
}

void bar() {
    std::cout << "bar: void" << std::endl;
}

void bar(int x) {
    while (x > 0) {
        std::cout << "bar: " << x << std::endl;
        x--;
    }
}

int main() {
    int x = 2, y = -1;
    bar();
    bar(x);
    foo(y);
    bar(foo());
}

Solution

bar: void
bar: 2
bar: 1
foo: -1 squared
foo: void
bar: 3
bar: 2
bar: 1

Find Index of First Repeated Element

Contributed by Xiaoxu Wu.

Given an array of integers and the size of the array, write a function firstRepeat that returns the index of the first repeated element. You may assume that there will be at least one duplicate element in the array.

Example

Input: int arr[] = {1, 2, 3, 2, 4}; int size = 5; Output: 3

Intput: int arr[] = {1, 2, 3, 7, 0, 2, 7, 3, 1}; int size = 9; Output: 5

Solution

We use two for loops to check every character. Once we find a repeated character, we update the index only if it is less than minIndex, which is initiated to the value n - 1 which is the largest possible value.

int firstRepeat(int arr[], int n) {
    int minIndex = n - 1;
    for (int i = 0; i < n; i++)
        for (int j = i + 1; j < n; j++)
            if (arr[i] == arr[j] && j < minIndex)
                minIndex = j;
    return minIndex;
}

Power Function

Contributed by Allison Ko.

Implement the power function:

float pow(float x, int y) {
    // your code here
}

Assume all inputs are valid. You don't have to check for errors.

Example

pow(2, 5) // returns 32
pow(12, -2) // returns -144
pow(0.5, 2) // returns 0.25

Solution

float pow(float x, int y) {
    float result = 1;
    if (y < 0) {
        for (int i = 0; i > y; i--) {
            result = result * (1.0/x);
        }
    } else {
        for (int k = 0; k < y; k++) {
            result = result * x;
        }
    }
    return result;
}

What is in foo?

Contributed by Kelvin Wong.

After this program is run, what is inside the array foo?

'int main() { int foo[10]; for (int x = 0; x < 10; x++) { foo[x] = x; } for (int y = 0; y < 5; y++) { foo[y + 5] = foo[y] + y; } } '

Solution

foo = {0,1,2,3,4,0,2,4,6,8}

int main() {
    int foo[10];
    for (int x = 0; x < 10; x++) {
        foo[x] = x; // makes foo = {0,1,2,3,4,5,6,7,8,9}
    }
    for (int y = 0; y < 5; y++) {
        foo[y + 5] = foo[y] + y; // changes foo to {0,1,2,3,4,0,2,4,6,8}
    }
}

Unique Numbers

Contributed by Henry Yang.

Find the number of unique numbers in an integer array. Function declaration: int numUnique(int a[], int size)

Example

//int test[10] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 8}; //numUnique(test) should return 8!

Solution

//This solution specifically works for array size 10 (because of picky markup rules needing a compile time constant). The heart of the function works for arbitrary size!

#include <iostream>
using namespace std;

const int kArraySize = 10;

int numUnique(int a[]) {

    // maintain a set of unique numbers
    int set[kArraySize];
    // maintain a count of unique numbers (also our return value)
    int ans = 0;
    for (int i = 0; i < kArraySize; i++) {
        bool repeat = false;
        for (int j = 0; j < ans; j++) {
            if (set[j] == a[i]) {
                repeat = true;
                j = ans;
            }
        }
        if (repeat) {
            // move on
        } else {
            set[ans] = a[i];
            ans++;
        }
    }
    return ans;
}

The Odd-Even Segregator!

Contributed by Michael Evangelista.

Write a function that takes an array of integers and orders the first n elements so that all even numbers are found before all odd numbers. Assume all arrays will have at most 20 elements.

Example

Given an array with the following elements: 1, 2, 3, 4, if sorting the first 6 elements, the function can return any of the following lines:

2, 4, 1, 3
4, 2, 1, 3
2, 4, 3, 1
4, 2, 3, 1

The important thing is that all even numbers are found before all odd numbers; the order of the even or odd numbers doesn't matter.

Solution

void arraySort(int arr[], int nElements) {
    int temp[SIZE];  // New array of max size
    int tempSize = 0;
    int odd[SIZE];  // Temp array for odds
    int oddSize = 0;
    for (int i = 0; i < nElements; i++) {
        if (arr[i] % 2 == 0) {  // If number is even
            temp[tempSize] = arr[i];  // Insert number to temp
            tempSize++;  // Increment tempsize
        } else {  // Number is off
            odd[oddSize] = arr[i];
            oddSize++;
        }
    }
    for (int j = 0; j < oddSize; j++) {
        temp[tempSize] = odd[j];
        tempSize++;
    }
    for (int k = 0; k < nElements; k++) {
        arr[k] = temp[k];  // Set values of arr to new values
    }
}

Rotate a string

Contributed by Xueyang Feng.

Write a function rotate that takes in a string s and “rotates” the string to the right k times.

Example

rotate(“abcde”, 1) returns “eabcd” rotate(“abcde”, 2) returns “deabc” rotate(“abcde”, 3) returns “cdeab” rotate(“abcde”, 7) returns “deabc”

Solution

#include <iostream>
#include <string>
using namespace std;

string rotate(string s, int k) {
  if (k < 0 || s.empty())
  return s;
  int toRotate = k % s.size();
  return s.substr(s.size() - toRotate) +
  s.substr(0, s.size() - toRotate);
}

int main() {
  string s = "abcde";
  rotate(s, 1);
  string s2 = "eabcd";
  if (s == s2)
  cout << "good";
}

Sneaky Chef

Contributed by Wandi Liu

Given two strings, trace the function chef() to find the output of main().

void chef(string &s1, string s2) {
    int m = s1.size();
    int n = s2.size();
    for (int i = 1; i <= min(m, n); i++) {
        // iterate the length of the shorter string
        if (s1[m-i] < s2[n-i]) {
            s1 = s1.substr(m-i+1);
            s2 = s2.substr(n-i+1);
            cout << i/2 << endl;
            break;
        } else if (s1[m-i] > s2[n-i]) {  // Hint: you'll break here!
            s1 = s1.substr(0, m-i+1);
            s2 = s2.substr(0, n-i+1);
            cout << i%2 << endl;
            break;
        } else {  // Hint: you'll hit this first!
            continue;
        }
    }
}

int main() {
    string s1 = "smoburger";
    string s2 = "nachoburger";
    chef(s1, s2);
    cout << s1 << endl << s2; 
}

Solution

Answer:

>> 0
>> sm
>> nachoburger
CAVEAT #1:

chef() will only permanently modify one of the parameters - s1 - which is passed by reference. The other, which is passed by value, will not be modified

CAVEAT #2:

A good understanding of for loops is needed because you will have to realize that the for loop is examining the two strings backwards (from index n-1 to 0)

CAVEAT #3:

The student should also understand the meaning of % (mod), this needs to be paired with the knowledge that that calling a function will executing its output statements


Add Strings

Contributed by Taoran Liu.

Given two positive integers, passed in as strings, return the sum of the two integers as a string. You may not assume that the strings are the same length or that the sum will be less than INT_MAX. You may assume that only the characters 0-9 will be in the string. Neither number will contain any leading zeros.

Example

stringSum("111", "111")

"222"

stringSum("999","91")

"1090"

stringSum("2147483647", "1")

"2147483648"

Solution

#include <iostream>

using namespace std;
// cs31 practice problem. given two strings, convert them into integers and add them

string stringSum(string num1, string num2) {
    string out = "";
    int i = 1;
    bool carry = false;

    while (num1.size() != num2.size()) {
        if (num2.size() > num1.size())
            num1 = '0'+num1;
        if (num1.size() > num2.size())
            num2 = '0'+num2;
    }

    for (;;) {
        int d1 = num1[num1.size()-i]-48, d2 = num2[num2.size()-i]-48;
        int tot = (d1+d2);
        if (carry) {
            tot++;
            carry = false;
        }
        char sum = tot%10 + 48;
        carry = tot/10;
        out = sum + out;
        i++;
        if (i > num1.size()) {
            if (carry) out = '1'+out;
            break;
        }
    }
    return out;
}



int main() {
    cout << stringSum("", "900");
    return 0;
}

Find the missing number in the array!

Contributed by Sahil Gandhi.

You are given an array of size 999 with the numbers 1-1000 in unsorted order. There are NO duplicates in this array. Your task is to find the one missing number in this array. Challenge: Can you do this without a secondary array?

Solution

int missingNumber(int size, int arr[]) {
    int expectedSum = (size)*(size+1)/2;
    int totalSum = 0;
    for (int i = 0; i < size; i++) {
         totalSum += arr[i];
    }
    return expectedSum - totalSum;
}

Not Enough Class?

Contributed by Yaacov Tarko.

Create a struct Student that stores the student's name as a string as the student's grade as an integer. Create a class Course that stores a string containing the course name (ex: "CS 31") and an array of Students. Course can have additional member variables as needed. Course name should be specified as an argument to the Course constructor, and should never change. Students should be added individually by a member function of Course, addStudent, that takes user input with cin and cout and returns 0 if it succeeds. A class can have up to 128 students, and if it has more than addStudent should return 1, output an error message, and not add the student. Now, write a function printStudents() that prints the names of students to the console in the order of their grades, from highest to lowest.

//
//  main.cpp
//  UPE CS31 problem
//
//  Created by Yaacov Tarko on 11/3/16.
//  Copyright © 2016 Yaacov Tarko. All rights reserved.
//

#include <iostream>
#include <string>


struct Student{
    std::string name;
    int grade;
};

class Course{
 public:
    // Don't worry about the 'explicit' keyword
    // I'm only using it in order to conform to Google's style guide
    // Your solution would be correct without it
    explicit Course(std::string course_name);
    int addStudent();
    int printStudents();

 private:
    std::string course_name;
    Student* students[128];
    int num_students;
};

Course::Course(std::string course_name) {
    this-> course_name = course_name;
    this-> num_students = 0;
}

int Course::addStudent() {
    // if there are too many students, don't add more
    if (num_students >= 128) {
        std::cout <<
        ""The course is already full. Please try to enroll next quarter"";
        return 1;
    }

    std::string student_name;
    int student_grade;

    std::cout << ""Please enter the student's name:"";
    std::cin >> student_name;

    std::cout << ""Please enter the student's grade"";
    std::cin >> student_grade;

    // make sure you use the new keyword to create this object!
    Student* new_student = new Student;

    new_student->name = student_name;
    new_student->grade = student_grade;

    students[num_students] = new_student;
    num_students++;

    return 0;
}
/*
 There are lots of ways you could implement this function.
 This one is very inefficient but it's easy to write quickly on an exam. 
 It iterates through the whole array and sorts it (using an algorithm called selection sort), 
 and then iterates through the sorted array and prints it with cout.
 */

int Course::printStudents() {
    // the location of the highest score in the unsorted part of the list.
    int maximum = 0;
    for (int i = 0; i < num_students-1; i++) {
        //  start by assuming the first unsorted student has the highest score
        maximum = i;
        for (int j = i; j < num_students; j++) {
            if (students[j]->grade > students[maximum]->grade) {
                maximum = j;
            }
        }
        // swap the highest scoring student with the next unsorted one
        Student *swap = students[maximum];
        students[maximum] = students[i];
        students[i]= swap;
    }
    // print the students' names and grades
    for (int i = 0; i < num_students; i++) {
        std::cout << students[i]->name << " " << students[i]->grade << "\n";
    }
    return 0;
}



// This is a tester. You wouldn't need to write it on the exam.
// I used it to make sure my code works properly.
int main(int argc, const char * argv[]) {
    Course CS31("CS31");
    for (int i = 0; i < 10; i++) {
        CS31.addStudent();
    }
    CS31.printStudents();
    return 0;
}



Sum of Primes

Kyle Liang.

Consider a number n. Find the sum of all prime numbers less than or equal to n.

Example

sumOfPrimes(2) = 2; sumOfPrimes(5) = 10; sumOfPrimes(12) = 28;

Solution

2 for loops. One to iterate numbers i to n, one to check if that number i is prime. There is an optimization for one for loop (see if you can find it).

#include <iostream>

using namespace std;

int sumOfPrimes(int x) {
    bool isPrime = true;
    int total = 0;
    for (int i = 2; i <= x; i++) {  // check all numbers up to n
        // check if number i is prime
        isPrime = true;
        for (int j = 2; j < i; j++) {
            if (i % j == 0) {
                isPrime = false;
                break;
            }
        }
        if (isPrime) {
            total += i;
        }
    }
    return total;
}

int main() {
    cout << sumOfPrimes(12) << endl;
}

Counting Inversions

Contributed by Vincent Cheng.

Write a function countInversions that takes in as parameters an array of numbers and the size of that array. This function should return the number of inversions in the array, or in other words, the number of times that, for two elements of different indexes, the element of greater index has a lesser value than the element of lesser index.

Examples

Array: 1, 3, 2
Size: 3
Inversions: 1

Array: 2, 3, 1, 5, 4
Size: 5
Inversions: 3

Solution

When two element have an inversion, that means that a[i] < a[j] when i > j for some array a. So it suffices to check for this condition for every element in the array; this can be accomplished with an outer loop through the elements of the array and an inner loop through the elements after the outer loop's element.

int countInversions(int* numArr, int size) {
  int totalInversions = 0;
  for (int x = 0; x < size; x++) {
    for (int y = x + 1; y < size; y++) {
      if (numArr[y] < numArr[x]) {
        totalInversions++;
      }
    }
  }
  return totalInversions;
}

Give me the change!

Contributed by Jiaming Zheng.

Write a function changeMachine(int cents) which, given an amount of money in cents, it will tell you how many coin of each type (quarter, dime, nickel or penny).

void changeMachine(int cents){
	



}

Example

`changeMachine(78) prints "3 quarter(s) 3 penny(s)" `
`changeMachine(15) prints "1 dime(s) 1 nickel(s)" `

Solution

#include <iostream>
using namespace std;
void changeMachine(int cents) {
    int quarters = 0, dimes = 0, nickels = 0, pennies = 0;
    while (cents > 0) {
        if (cents >= 25) {
            cents -= 25;
            quarters++;
        } else if (cents >= 10) {
            cents -= 10; 
            dimes++;
        } else if (cents >= 5) {
            cents -= 5; 
            nickels++;
        } else {
            cents -= 1; 
            pennies++;
        }
    }
    if (quarters > 0)
        cout << quarters << " quarter(s) ";
    if (dimes > 0)
        cout << dimes << " dime(s) ";
    if (nickels > 0)
        cout << nickels << " nickel(s) ";
    if (pennies > 0)
        cout << pennies << " cent(s) ";
}
int main() {
}

Code Tracing

Contributed by Luke Moore.

What does the following code output?

#include <iostream>
using namespace std;

int main() {
  int numbers[9];
  int * p;
  p = numbers;
  *p = 1;
  *(p+3) = 2;
  p++;
  *p = 3;
  p = &numbers[5];
  *(p--) = 4;
  p = p + 4;
  *p = 5;
  *(--p) = 6;
  p = numbers + 2;
  *(p++) = 7;
  *(++p) = 8;
  numbers[6] = 9;

  for (int n = 0; n < 9; n++) {
    cout << numbers[n] << endl;
  }

  return 0;
}

Solution

  1
  3
  7
  2
  8
  4
  9
  6
  5

Pointer Practice

Contributed by Shannon Tom.

Does this program successfully compile? If so, what is the output? If not, explain why. Assume all necessary headers are included.

void add(int x, int y) {
    x += y;
}

int main() {
  int arr[5] = {5, 1, 7, 2, 9};
  int a;
  int *p, *b;
  a = arr[1];
  p = arr + a;
  b = p;
  a++;
  b++;
  *b = 3;

  cout << *(p+a) << endl;
  cout << *arr << endl;

  add(*(p+a), *arr);

  cout << *(p+a) << endl;
  cout << *arr << endl;
  cout << a << *p << *b << endl;
}

Solution

Correct Output: 2 5 2 5 213

For the correct output, trace through the code as follows:

void add(int x, int y) {                       
                      // x = 2, y = 5
  x += y;             // x = 2 + 5 = 7
}

int main() {
  int arr[5] = {5, 1, 7, 2, 9};
  int a;
  int *p, *b;
  a = arr[1];         // a = 1
  p = arr + a;        // p = &arr[1]. p points to arr[1]
  b = p;              // b points to arr[1]
  a++;                // a = 2. Add one to a
  b++;                // b = &arr[2]. b points to arr[2]
  *b = 3;             // the int of arr[2] is now 3 

  cout << *(p+a) << endl;         // *arr[3] = 2
  cout << *arr << endl;           // *arr = 5

  add(*(p+a), *arr);              // Arguments are passed by value.
                                  // original values are not altered

  cout << *(p+a) << endl;         // *arr[3] = 2 (same as previous values)
  cout << *arr << endl;           // *arr = 5 (same as previous values)
  cout << a << *p << *b << endl;  // a = 2, *p = 1, *b = 3
}

Convert Integer to Array of Digits

Contributed by James Mullen.

Given a positive integer, write a method convert_to_digit_array that returns an array of 10 integers. Each value in the array should correspond to the count of that digit in the given integer.

Example

1 -> [0, 1, 0, 0, 0, 0, 0, 0, 0, 0] 1357924680 -> [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] 4844 -> [0, 0, 0, 0, 3, 0, 0, 0, 1, 0]

Solution

int[] convert_to_digit_array(int i) {
  int[10] digits;
  for (int j = 0; j < 10; j++) {
    digits[j] = 0;
  } 

  while (i > 0) {
    int digit = i % 10;
    digits[digit]++;
    i = i/10;
  }
  return digits;
}

Create a new Identity Matrix

Contributed by Yuhuang Chen.

Create a dynamically allocated n x n identity matrix (a two dimensional array with n rows and n columns). Initialize the elements on the main diagonal to 1, and others to 0. Parameters: a int type to indicate matrix size Return type: a double pointer of int type

Example

If n = 2, the matrix should look like 10 01

If n = 3, the matrix should look like 100 010 001

/*
Create a dynamically allocated n x n identity matrix (a two dimensional array with n rows and n columns). Initialize the elements on the main diagonal to 1, and others to 0.
*/

int** creat_identity_matrix(int n) {
  int** ret;
  ret = new int* [n];
  for (int i = 0; i < n; i++)
    ret[i] = new int[n];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (i == j)
        ret[i][j] = 1;
      else
        ret[i][j] = 0;
    }
  }
  return ret;
}

Palindromic Number

Jun Kai Ong.

Write a function isPalindromicNum that returns whether a given positive integer is a palindromic number sequence. (A palindromic number sequence is a number that reads the same backwards as forwards.)

Example 1

int n = 123;
cout << isPalindromicNum(n); // outputs false

Example 2

int n = 1;
cout << isPalindromicNum(n); // outputs true; 

Example 3

int n = 1221;
cout << isPalindromicNum(n); // outputs true; 

Solution

bool isPalindromicNum(int num) {
    int n = num; 
    int backwards = 0;
    while (n != 0) {
        backwards += n % 10;
        n /= 10;
        if (n == 0)
            break;
        backwards *= 10;
    }
    if (backwards != num)
        return false;
    else
        return true;
}

Vigenèrian Vexations

Contributed by Eric Kong.

Background

Suppose you're writing a message to your secret lover. Suppose, in fact, that its contents are so mind-bogglingly embarrassing (if not incriminating) that dire consequences threaten to befall you both were it to fall into the wrong hands. It would be wise, therefore, to conceal the message in such a way that only your paramour could read it. Hence the basic motivation for the wondrous field of encryption, the secure transmission of confidential information to entrusted recipients only. From forbidden lovers to government agents, resistance operatives, and beyond, encryption makes the world go 'round.

More abstractly, we concern ourselves with the following problem. Given a raw specimen of text, or plaintext, to be encrypted, and an encryption key, we wish to produce an encrypted text, or ciphertext. (The converse problem, deducing a plaintext from a ciphertext given a key, is called, funnily enough, decryption.) A mechanism for performing encryption or decryption is called a cipher. One simple example of a cipher is the Caesar cipher: given a plaintext and a number x from 0 to 25, shift every letter in the plaintext by x places in the alphabet.

Naturally, some ciphers are stronger than others. In fact, cryptanalysts concern themselves wih the problem of breaking ciphers, or extracting the plaintext from the ciphertext without a key. The Caesar cipher is, alas, easily broken. So is its cousin the substitution cipher (replace every instance of a letter with another letter), stymied by simple letter frequency analysis. Hence these are seldom used in contemporary private correspondence.

The Vigenère cipher is a simple yet relatively strong cipher, considered nigh unbreakable for three centuries. Perhaps it is best illustrated through example. Suppose we have the plaintext ILOVEYOUSMALLBERG. Let's encrypt it with the key CAREY in the following manner. First, we extend the key by repetition to the length of the plaintext:

ILOVEYOUSMALLBERG
CAREYCAREYCAREYCA

Now let's establish an alphanumeric correspondence: A corresponds to 0, B to 1, and so on and so forth, and Z to 25. Consider the first character of the plaintext, I, and that of the key, C. I corresponds to 8, and C to 2. We add the numbers (modulo 26) to obtain 10, which corresponds to K. Thus the first letter of the ciphertext is K. We proceed similarly for every letter in the plaintext. The full ciphertext thus produced by the operation is KLFZCAOLWKCLCFCTG, as below:

ILOVEYOUSMALLBERG
CAREYCAREYCAREYCA
-----------------
KLFZCAOLWKCLCFCTG

Problem

Implement a function vigenere which takes two string arguments, plaintext and key, and applies the Vigenère cipher to obtain a ciphertext, which it should return as an uppercase string. Because we are nice, you may assume that plaintext and key consist solely of uppercase letters 'A'-'Z', that key is nonempty, and that you are working in ASCII. Friendly hint: In ASCII, the characters 'A' through 'Z' occur contiguously and in order.

We graciously provide you a function prototype for vigenere below.

string vigenere(string plaintext, string key);

Example

The function call vigenere(""ILOVEYOUSMALLBERG"", ""CAREY"") shall return the string ""KLFZCAOLWKCLCFCTG"", as per the above example.

Solution

In our solution, we iterate through the plaintext letter by letter. A few items of note:

  • To simulate the key being repeated as long as is necessary, we apply the modulus operator % to the counter i so that it cycles within the key's length.
  • We establish the aforementioned alphanumeric correspondence by subtracting 'A' from the relevant character. Recall that characters are essentially integers, and in character arithmetic, 'A' - 'A' = 0, 'B' - 'A' = 1, and so on and so forth, and 'Z' - 'A' = 25. (Note that this only works in nice encoding scheme like ASCII, where 'A'-'Z' are contiguous. Things would go awry, for example, if we worked with that curious dinosaur of an encoding protocol, EBCDIC.)
  • Similarly, to reconstruct the character in the ciphertext, cipherChar, we add an integer from 0 to 25 back to 'A'.
  • It's necessary to apply the % 26 operation, as the addition may overflow 25.
  • The cleverer of you problem-solvers may observe that the contents of the for-loop can be compressed into one line. We believe that in well-written code, readability trumps compactness, and accordingly we separate our steps in the calculation.
#include <string>
using namespace std;

string vigenere(string plaintext, string key) {
    string ciphertext;

    for (size_t i = 0; i < plaintext.length(); i++) {
        char plainChar = plaintext[i];
        char keyChar = key[i % key.length()];

        char cipherChar = 'A' + (((plainChar - 'A') + (keyChar - 'A')) % 26);
        ciphertext += cipherChar;
    }

    return ciphertext;
}

Fill in the blank to complete the function with given requirement

Contributed by Yujing Fan.

Below is a code segment for the class Student, fill in the blank of functions Student (int ID, int grade, string name, Student* nextStudent); getgrade(); get_nextGrade(); updateGrade(int score);!

Solution

// write the code for the blank function

#include<stdio.h>
#include<iostream>
#include<string>
using namespace std;

class Student {
    public:
        Student() {
            Student_ID = 0;
            Student_grade = 0;
            Student_name = """";
            next_Student = nullptr;
        }
        Student(int ID, int grade, string name, Student* nextStudent);

        int getID() {
            return Student_ID;
        }/*return the ID of current student*/

        int getgrade() {
            return Student_grade;
        }/*return the grade of current student*/

        string getname() {
            return Student_name;
        }/*return the name of current student*/

        Student* getNextstudent() {
            return next_Student;
        }/*return the pointer that points to the next student*/

        int updateGrade(int score) {
            Student_grade = score;
        }  // update the current grade with new score

        int get_nextGrade() {
            return next_Student->getgrade();
        }  // return the grade of next student

    private:
        int Student_ID;
        int Student_grade;
        string Student_name;
        Student* next_Student;
    };
    Student::Student(int ID, int grade, string name, Student* nextStudent) {
    Student_ID = ID;
    Student_grade = grade;
    Student_name = name;
    next_Student = nextStudent;
}

Finding Program Errors

Contributed by Miranda Ku.

The following code is supposed to print the numbers from 0 to 5, as follows:

0
1
2
3
4
5

However, it does not. Identify the problems in the code below. You need not make actual fixes (the code is too flawed). You should be able to identify two major problems.

(Note that this code is unreasonably convoluted. The problem is simply meant to help you identify code problems, so just roll with it.)

#include <iostream>
#include <stdlib.h>
#include <time.h>

int* badFunc() {
int x, y[6];
x = 0;
for (; x < 6; x++) {
y[x] = x;
}

int *copy = y;
for (; x < 5; x++) {
std::cout << *copy << std::endl;
copy++;
}
return copy;
}

void trample() {
unsigned int seed = time(NULL);
int x[100000];
for (int i = 0; i < 100000; i++)
x[i] = rand_r(&seed);
}

int main() {
int* ret = badFunc();
trample();
std::cout << *ret << std::endl;
}

Solution

The first problem is that the second loop is never being entered because x's value is 6. Thus it will never be less than 5 and the printing loop is never entered. Secondly, the function returns a local address which is then freed for the computer to be able to reuse, which the function trample() aids with. Thus printing this address is erroneous. Fixing this problem with this current code structure seems to be a useless exercise, as there are simply much better ways to write a program that does the same thing, so don't worry about it.


Alpha To Sum

Contributed by Tyler Lindberg.

Given an array of characters, return the sum of their indices in the alphabet. The indexing will begin from 0, so a = 0, b = 1, c = 2, ..., z = 25. Both uppercase and lowercase letters should be mapped to the same index. If there are any non-alphabetical characters in the array, return -1.

Given Code:

#include <iostream>
int alphaSum(int a[], int size);

Example

Input : a, d, f, b
Answer: 0 + 3 + 5 + 1 = 9
Output: 9

Solution

int alphaSum(int a[], int size) {
int sum = 0;

// Store int value of a, since we want to count up from there
int aIndex = static_cast<int>('a');

for (int i = 0; i < size; i++) {
// Check if a[i] is a letter
if (!isalpha(a[i]))
return -1;

// Add on the ASCII value of the current char minus the ASCII value of 'a'
// This results in 'a' having an index of zero and 'z' having an index of 25
// Note that a[i] is converted to lower case using tolower first
sum += static_cast<int>(tolower(a[i])) - aIndex;
}

return sum;
}

Code Tracing with Arrays, Pointers and Functions

Contributed by Ayush Rath.

Trace through main() and determine the output

#include <iostream>

using namespace std;

void convolve(int* a, int* b, int* c, int na, int nb, int nc) {
int tmp[7];
for (int* i = a; i < a + na; i++) {
int index = i - a;
tmp[na - index - 1] = *i;
}

for (int i = 0; i < nc; i++) {
int k = i;
int val = 0;
for (int j = 0; j < nb; j++) {
if (k >= 0 && k < na) {
val += (a[k] * b[j]);
}
k--;
c[i] = val;
}
}
}

int main() {
int a[7] = { 0, 0, 0, 1, 1, 1, 1 };
int b[7] = { 0, 0, 0, 8, 4, 2, 1 };
int c[13];

convolve(a, b, c, 7, 7, 13);

for (int i = 0; i < 13; i++) {
cout << c[i];

if (i % 2 == 0) {
cout << endl;
} else {
cout << "" "";
}
}
return 0;
}

Solution

In convolve() the first for loop reverses a and stores it in tmp. The second for loop determines what values are stored in c. Run through a few iterations to determine what is happening.

First iteration: The first element of b is multiplied by the last element of a, the result is stored in c[0]

Second Iteration: The first two elements of b are multiplied by the last two elements of a, the sum of the products is stored in c[0].

Take note of the pattern and extrapolate:

1:

*******
*******

2:

*******
*******

3

*******
*******

...

13:

*******
*******

When the contents of c are printed, there is a line break after every even indexed element, note that arrays in C++ start with an index of 0.

So the solution is:

0
0 0
0 0
0 8
12 14
15 7
3 1

Reverse words in strng

Contributed by Ginny Wang.

Given an input string, reverse the string word by word (separated by space).

Example

Input: "the brown fox"

Output: "eht nworb xof"

Solution

#include <string>
#include <algorithm>
using namespace std;


// you can also implement your own reverse function

string reverseWords(string s) {
    string str = "";
    int l = s.size();
    if (!l)
        return;
    reverse(s.begin(), s.end());
    int index = 0;
    for (int i = 0; i < l; i++) {
        if (s[i] != ' ') {
            if (index != 0) 
            s[index++] = ' ';
            int j = i;
            for (j = i; j < l && s[j] != ' '; j++) {
                s[index] = s[j];
                index++;
            }
            reverse(s.begin()+index-(j-i), s.begin()+index);
            i = j;
        }
    }
    s.erase(s.begin()+index, s.end());
    return s;
}

Encrypting a String (string manipulation)

Contributed by Kaitlyn Cason.

One simple way to encrypt text is to write all of the even-index (starting at 0) characters, followed by all of the odd index characters, ignoring punctuation and whitespace. For example, we might encode "I love CS133" as "IoeS3lvC13". Write a method called encrypt that takes a String as a parameter and returns a new String object that represents the result of encrypting the parameter String. Complete the method signature and the body of the method below::

Example

Input: "I love CS31"
Output: "IoeS3lvC13"
Input: ""
Output: ""
Input: "look!at!this!encryption!"
Output: "loatiecytookthsnrpin"

Solution

#include <iostream>
#include <stdio.h>
using namespace std;

string encrypt(string source) {
    // Initialize strings for odds and evens
    string odds = "";
    string evens = "";

    // Since we index at 0, isEvens starts off TRUE
    bool isEvens = true;

    for (int i = 0; i < source.length(); i++) {
        char c = source[i];
        // Ignore whitespace and punctuation
        if (isalpha(c) || isdigit(c)) { 
            if (isEvens) {
                evens += c;
            } else {
                odds += c;
            }
            // Keep track of index (odd/even)
            isEvens = !isEvens;
        }
    }
    return evens + odds;
}

Compress strings

Contributed by Jerry Liu.

Given a string, write a function that returns a compressed string. Assume an empty string returns empty string. You are allowed to use the built-in to_string function.

Example

Given "aaaaabbbc", the function should return "5a4b1c". Given "1", the function should return "11".

Solution

The only tricky part is the line right before return result, which includes the last set of characters and corresponding count. The code inside the for loop does not take care of the last set of characters. During an exam, make sure you go through your code with some input!

#include <iostream>
#include <string>
using namespace std;

string compress(const string& s) {
    if (s.empty())
        return s;
    string result;
    char prev = s[0];
    int count = 1;
    for (int i = 1; i < s.size(); i++) {
        if (prev == s[i]) {
            count++;
        } else {
            result += to_string(count) + prev;
            prev = s[i];
            count = 1;
        }
    }
    result += to_string(count) + prev;
    return result;
}

int main() {
    string s = "aaaaabbbc";
    cout << compress(s) << endl;
    s = "c";
    cout << compress(s) << endl;
}

Move Zeroes

Contributed by Regan Hsu.

Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements.

Example

For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0]

Solution

#include <iostream>
#include <vector>
#include <algorithm>    
using namespace std;

void moveZeroes(vector<int> nums) {
    int j = 0, i = 0;
    for (; i < nums.size(); i++, j++) {
        if (nums[i] == 0) {
            while (i < nums.size()-1 && nums[i] == 0) {
                i++;
            }
        }
        nums[j] = nums[i];
    }
    while (j < i) {
        nums[j] = 0;
        j++;
    }
}

Add Strings as Integers

Contributed by Changfei Shi.

Given two non-negative numbers num1 and num2 represented as strings, return the sum of num1 and num2.

Note:

  1. Both num1 and num2 contains only digits 0-9.
  2. Both num1 and num2 do not contain any leading zero.
  3. You cannot use the function atoi or otherwise directly convert string to integer or vice versa.

Solution

string addStrings(string num1, string num2) {
    int i = 0;
    int carry = 0;
    string sum = """";
    while (i &lt; num1.size() || i &lt; num2.size()) {
        int a, b;
        // Convert both of the values to their integer representations
        if (i &lt; num1.size())
            a = (num1[num1.size() - 1 - i]) - '0';
        else
            a = 0;
        if (i &lt; num2.size())
            b = (num2[num2.size() - 1 - i]) - '0';
        else
            b = 0;
        // Check for the sum of the two values + the carry value
        sum = static_cast<char>((a + b + carry) % 10 + '0') + sum;
        if ((a + b + carry) &gt;= 10)
            carry = 1;
        else
            carry = 0;
        i++;
    }
    if (carry == 1) {
        sum = '1' + sum;
    }
    return sum;
}

Bulls and Cows

Contributed by Your Gabriel Zhou.

You are playing the following Bulls and Cows game with your friend: You write down a number and ask your friend to guess what the number is. Each time your friend makes a guess, you provide a hint that indicates how many digits in said guess match your secret number exactly in both digit and position (called "bulls") and how many digits match the secret number but locate in the wrong position (called "cows"). Your friend will use successive guesses and hints to eventually derive the secret number.

Example

Secret number:  "1807"
Friend's guess: "7810"

Hint: 1 bull and 3 cows. (The bull is 8, the cows are 0, 1 and 7.)

Write a function to return a hint according to the secret number and friend's guess, use A to indicate the bulls and B to indicate the cows. In the above example, your function should return "1A3B".

Please note that both secret number and friend's guess may contain duplicate digits, for example:

Secret number:  "1123"
Friend's guess: "0111"

In this case, the 1st 1 in friend's guess is a bull, the 2nd or 3rd 1 is a cow, and your function should return "1A1B". You may assume that the secret number and your friend's guess only contain digits, and their lengths are always equal.

string getHint(string secret, string guess) {
    int len = secret.size();
    int bnum = 0, cnum = 0;    // bnum: number of bulls, cnum: number of cows
    vector<int> cnt1(10, 0), cnt2(10, 0);
    for (int i = 0; i < len; i++) {
        int n1 = secret[i] - '0', n2 = guess[i] - '0';
        if (n1 == n2) { 
            bnum++;
        } 
        else {
            if (cnt2[n1]) {
                cnum++;
                cnt2[n1]--;
            } 
            else { 
                cnt1[n1]++;
            }

            if (cnt1[n2]) {
                cnum++;
                cnt1[n2]--;
            } 
            else {
                cnt2[n2]++;
            }
        }
    }
    return to_string(bnum) + "A" + to_string(cnum) + "B";
}


Remove character from string

Contributed by Robert Zalog

Implement the function provided by the following function header:

void removeCharacter(char *cstring, char c);,

which removes the character c from the C-string cstring. There is guaranteed to be only one instance of the character c in cstring.

Example

Example function call:

// cstring defined as "hello world"
removeCharacter(cstring, 'w');
// cstring is now "hello orld"

An example of invalid input:

// cstring defined as "hello world"
removeCharacter(cstring, 'l');
// invalid output, more than one instance of 'l' in cstring

Solution

void removeCharacter(char *cstring, char c)
{
  char *temp;
  for ( ; *cstring != '\0'; cstring++) {
    if (*cstring == c) {
      temp = cstring+1;
      while (*cstring != '\0') {
        *cstring = temp;
        cstring++;
      }
    }
  }
}

Possible Palindrome

Shaan Mathur.

Given a string, can you determine if we can form a palindrome using those letters? Don't worry about actually rearranging the letters, we just want to see if it's possible.

Write a function possiblePalindrome that takes a string as an argument and returns a bool. This function should return true if the letters in the string can be rearranged such that a palindrome can be formed. If not, it should return false.

Example

racecar -> true
racecra -> true
rcaearc -> true
racecara -> false

Solution

#include <string>

using namespace std;

// We want to determine whether the given string can be rearranged to form
// a palindrome. In other words, there should be an even amount of letters of each type.

// NOTE: This is a CS31 approach to the problem. In CS32, you will learn approaches that are
// even cooler, faster, and more interesting than this approach.


bool possiblePalindrome(string word) {
    char foundOdd = '\0';
    for (int i = 0; i < word.size(); i++) {
        int count = 0;  // number of instances of word[i]
        for (int j = 0; j < word.size(); j++) {
            if (word[i] == word[j])
                count++;
        }
        // If there is an even amount, then there should be a way to rearrange the
        // characters so that we can form a palindrome (since we can divide them 
        // and place each half on each side of our palindrome.

        // If there is an odd amount, then that is acceptable if word is of odd size 
        // (one character in the middle will have no matching pair) and there an odd 
        // amount occurs only once (only ONEcharacter has no matching pair).

        if (count % 2 == 1) {
            // count is odd so we have one unmatched pair
            if (word.size() % 2 == 1 && (foundOdd == '\0' || foundOdd == word[i])) {
                // word size is odd and we hadn't found an unmatched pair before (or 
                // we did, but for this letter), so it's okay
                foundOdd = word[i];
                continue;
            } else {
                // word size is even OR we already found an unmatched pair before. 
                // Either way, this doesn't work
                return false;
            }
        }
    }

    return true;  // We were able to check every letter successfully! We CAN form a palindrome!
}

/* Closing thoughts... 

Is there a case where this function wouldn't work? It's subtle, but possible. Think about it...

(And an optional hint to motivate CS32)

Is there anything about this implementation that seems unnecessary? If the string was of length
10, how many times would we check if word[i] == word[j]? How about 100? 1000? How about for 
arbitrary N?

Believe it or not, if you take CS32 you'll figure out how to do this with only one for loop... :)
*/

Clone this wiki locally