CS106B Assignment 1: Welcome Back to C++

ISN’T IT A HAPPY THING IF YOU REVIEW WHAT YOU HAVE LEARNED ON TIME?
—   THE ANALECTS OF CONFUCIUS, CONFUCIUS, 500 BC

Most of the assignments in this course are single programs of a substantial size. To get you started, however, this assignment is a series of four short problems that are designed to get you used to file I/O operation in C++ and to introduce the idea of functional recursion. None of these problems require more than a page of code to complete; most can be solved in just a few lines.

Problem 1-Adding Commas

When large numbers are written out on paper, it is traditional—at least in the United States—to use commas to separate the digits into groups of three. For example, the number one million is usually written in the following form:

1,000,000

To make it easier for programmers to display numbers in this fashion, implement a function

string addCommas(string digits);

that takes a string of decimal digits representing a number and returns the string formed by inserting commas at every third position, starting on the right. For example, if you were to execute the main program:

int main() {
  while (true) {
  string digits = getLine("Enter a number: ");
  if (digits == "") break;
    cout << addCommas(digits) << endl;
  }
  return 0;
}

your implementation of the addCommas function should be able to produce the following sample run:

Enter a number: 17
17
Enter a number: 1001
1,001
Enter a number: 12345678
12,345,678
Enter a number: 999999999
999,999,999
Enter a number:

问题分析与算法设计

由于数字长度在<4的情况下可以不用加逗号直接输出结果,因此考虑使用递归的方式来设计算法。具体为:

当digits长度<4,函数直接返回原数字,否则返回’函数(digits[0:-3])+”,”+digits[-3:]’;

代码

/*
 * File: AddCommas.cpp
 * -------------------
 * Name: [TODO: enter name here]
 * This program adds commas to numeric strings.
 * [TODO: rewrite the documentation]
 */

#include <iostream>
#include <string>
#include "simpio.h"
#include "console.h"
using namespace std;

/* Function prototypes */

string addCommas(string digits);

/* Main program */

int main() {
   while (true) {
      string digits = getLine("Enter a number: ");
      if (digits == "") break;
      cout << addCommas(digits) << endl;
   }
   return 0;
}

/*
 * Function: addCommas
 * Usage: string str = addCommas(digits);
 * --------------------------------------
 * Adds commas at every third position of the string digits
 * starting on the right.
 */

string addCommas(string digits) {
    if digits.s
    // [TODO: modify and fill in  the code]
   return "";

}

实验小结

需要注意string类的字符串索引切片需要借用substr函数来进行。

Problem 2-Sorting File Data

C/C++ IO are based on streams, which are sequence of bytes flowing in and out of the programs (just like water and oil flowing through a pipe). In input operations, data bytes flow from an input source (such as keyboard, file, network or another program) into the program. In output operations, data bytes flow from the program to an output sink (such as console, file, network or another program). Streams acts as an intermediaries between the programs and the actual IO devices, in such the way that frees the programmers from handling the actual devices, so as to archive device independent IO operations.

C++ provides both the formatted and unformatted IO functions. In formatted or high-level IO, bytes are grouped and converted to types such as int, double, string or user-defined types. In unformatted or low-level IO, bytes are treated as raw bytes and unconverted. Formatted IO operations are supported via overloading the stream insertion (<<) and stream extraction (>>) operators, which presents a consistent public IO interface.

To perform input and output, a C++ program:

  1. Construct a stream object.
  2. Connect (Associate) the stream object to an actual IO device (e.g., keyboard, console, file, network, another program).
  3. Perform input/output operations on the stream, via the functions defined in the stream’s pubic interface in a device independent manner. Some functions convert the data between the external format and internal format (formatted IO); while other does not (unformatted or binary IO).
  4. Disconnect (Dissociate) the stream to the actual IO device (e.g., close the file).
  5. Free the stream object.

Now there is a text format file (named as “raw-data.txt”) containing several lines of integers. Your program can solove:

Task 1:Read out the data from raw-data.txt for sorting, and output the result to a binary format file named as sorted-data.bin.
Task 2:Read out the data from sorted-data.bin, find out the median and output to the screen.

Note: Starter files contain raw-data.txt, and your program needs to create sorted-data.bin.

问题分析与算法设计

该实验两部分的大致解决思路如下:

Task A:从txt文件读取字符-字符写入到字符串-字符串转换为数组-数组排序-数组转换为字符串-字符串写入bin文件

Task B:从bin文件读取字符-字符写入到字符串-字符串转换为数组-从数组中提取中位数-输出

代码

/*
 * File: sortingfiledata.cpp
 * -------------------
 * Name: [TODO: enter name here]
 * This program sorts integers read from the text file.
 * [TODO: rewrite the documentation]
 */

#include <fstream>
#include <string>
#include <cctype>
#include "error.h"
#include "filelib.h"
#include "console.h"
#include "simpio.h"

using namespace std;

/* Main program */

int main(){

    // Here, we assume that the number of integers in raw-data.txt does not exceed 100
    int data[100], counter = 0;
    // ------------ Beginning of Task A  ------------
    // Read out the data from raw-data.txt for sorting,
    // and output the result to a binary format file named as sorted-data.bin.
    // Open text format file as input file stream
    ifstream ift("raw-data.txt");
    // Open binary format file as output file stream
    ofstream ofb("sorted-data.bin", ios::binary);

    if(!ift.fail()) {  // If the input stream is opened successfully
        while(!ift.eof()){   // If the file stream does not reach the end of file

        // [TODO: fill in  the code here]
        // Read out the data from input stream and assign it to data array

        }
    }
    else
    {
        cout << "open file error!" << endl;
        return -1;
    }

    // [TODO: fill in  the code]
    // sort data array and output to output stream

    ift.close();
    ofb.close();
    // ------------  End of Task A  ------------

    // ------------ Beginning of Task B  ------------
    // Read out the data from sorted-data.bin, find out the median and output to the screen.
    // Open binary format file as input file stream
     ifstream ifb("sorted-data.bin", ios::binary);
     if(!ifb.fail()) {  // If the input stream is opened successfully
         while(!ifb.eof()){   // If the file stream does not reach the end of file

         // [TODO: fill in  the code here]
         // Read out the data from input stream, find out
         // the median and output to the screen.

         }
     }
     else
     {
         cout << "open file error!" << endl;
         return -1;
     }

     ifb.close();
     // ------------  End of Task B  ------------


    return 0;
}

实验小结

1.读取字符使用get函数,写入字符使用put函数;

2.出于简化代码目的,额外声明了三个函数:

void str2arr(string str,int* arr ,int &counter);      // 将字符串转换为数组
void read_char(ifstream &file,string &str);          // 从文件中读取字符并且写入字符串
double findMed(int arr[],int len);                  // 给定数组与长度,求出中位数

3.排序算法直接引用了<algorithm>库中的sort函数;

4.问题:通过当前算法读取到的字符串会出现最后一个数字的最后一个数位出现重复(比如在本题中会将最后一个数字“92”读取成“922”),目前采用的解决方案是将str2arr中的字符串遍历中直接略去最后一位(即i<str.size()-1),但是该问题产生原因未知,此解决方案也许会忽略掉本就正确的读取结果(推测)。

Problem 3-Finding DNA Match

There is no gene for the human spirit.
——Tagline for the 1997 film GATTACA

The genetic code for all living organisms is carried in its DNA—a molecule with the remarkable capacity to replicate its own structure. The DNA molecule itself consists of a long strand of chemical bases wound together with a similar strand in a double helix. DNA’s ability to replicate comes from the fact that its four constituent bases—adenosine, cytosine, guanine, and thymine—combine with each other only in the following ways:

  • Cytosine on one strand links only with guanine on the other, and vice versa.
  • Adenosine links only with thymine, and vice versa.

Biologists abbreviate the names of the bases by writing only the initial letter: A, C, G, or T.

Inside the cell, a DNA strand acts as a template to which other DNA strands can attach themselves. As an example, suppose that you have the following DNA strand, in which the position of each base has been numbered as it would be in a C++ string:

Your mission in this exercise is to determine where a shorter DNA strand can attach itself to the longer one. If, for example, you were trying to find a match for the strand

the rules for DNA dictate that this strand can bind to the longer one only at position 1:

By contrast, the strand matches at either position 2 or position 7.

Write a function

int findDNAMatch(string s1, string s2, int start = 0);

that returns the first position at which the DNA strand s1 can attach to the strand s2. As in the find method for the string class, the optional start parameter indicates the index position at which the search should start. If there is no match, findDNAMatch should return –1.

问题分析与算法设计

该程序为一系列函数的嵌套

main:主函数

└─findAllMatches: Finds all positions at which s1 can bind to s2.

└─findDNAMatch: Returns the first index position ……

└─matchingStrand: A-T,C-G

需要完成的部分中:

matchingStrand使用for循环遍历字符串+switch-case语句替换字符

findDNAMatch使用string类的find方法进行匹配

代码

/*
 * File: FindDNAMatch.cpp
 * ----------------------
 * Name: [TODO: enter name here]
 * This file solves the DNA matching exercise from the text.
 * [TODO: rewrite the documentation]
 */

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

/* Prototypes */

int findDNAMatch(string s1, string s2, int start = 0);
string matchingStrand(string strand);
void findAllMatches(string s1, string s2);

/* Main program */

int main() {
   findAllMatches("TTGCC", "TAACGGTACGTC");
   findAllMatches("TGC", "TAACGGTACGTC");
   findAllMatches("CCC", "TAACGGTACGTC");
   return 0;
}

/*
 * Function: findAllMatches
 * Usage: findAllMatches(s1, s2);
 * ------------------------------
 * Finds all positions at which s1 can bind to s2.
 */

void findAllMatches(string s1, string s2) {
   int start = 0;
   while (true) {
      int index = findDNAMatch(s1, s2, start);
      if (index == -1) break;
      cout << s1 << " matches " << s2 << " at position " << index << endl;
      start = index + 1;
   }
   if (start == 0) {
      cout << s1 << " has no matches in " << s2 << endl;
   }
}


/*
 * Function: findDNAMatch
 * Usage: int pos = findDNAMatch(s1, s2);
 *        int pos = findDNAMatch(s1, s2, start);
 * ---------------------------------------------
 * Returns the first index position at which strand s1 would bind to
 * the strand s2, or -1 if no such position exists.  If the start
 * parameter is supplied, the search begins at that index position.
 */

int findDNAMatch(string s1, string s2, int start) {

    // [TODO: modify and fill in the code]
    return -1;

}

实验小结

发现string类的find方法在未找到匹配序列时会返回一个极大数而非-1,因而使用条件语句语句waiting_pair.find(matchingStrand(s1))<waiting_pair.size()判断,为false时将控制返回-1

Problem 4-Only Connect

The last round of the British quiz show Only Connect consists of puzzles of the following form: can you identify these movie titles, given that all characters except consonants have been deleted?

BTNDTHBST  MN  CTCHMFCN            SRSMN

The first is “Beauty and the Beast,” the second is “Moana,” the third is “Catch Me If You Can,” and we’ll leave the last one as an exercise to you.

To form a puzzle string like this, you simply delete all characters from the original word or phrase except for consonants, then convert the remaining letters to ALL-CAPS.

Your task is to write a recursive function

string onlyConnectize(string phrase);

that takes as input a string, then transforms it into an Only Connect puzzle. For example:

  • onlyConnectize(“Elena Kagan”) returns “LNKGN”,
  • onlyConnectize(“Antonin Scalia”) returns “NTNNSCL”,
  • onlyConnectize(“EE 364A”) returns “”,
  • onlyConnectize(“For sale: baby shoes, never worn.”) returns “FRSLBBSHSNVRWRN”,
  • onlyConnectize(“I’m the bad guy. (Duh!)”) returns “MTHBDGDH”, and
  • onlyConnectize(“Annie Mae, My Sea Anemone Enemy!”) returns “NNMMSNMNNM”.

The starter code that we’ve provided contains code to test your function on certain inputs. These tests check a few sample strings and are not designed to be comprehensive. In addition to implementing the onlyConnectize function, you will need to add in at least one new test of your own using theADD_TEST macro. To do so, use this syntax:

ADD_TEST("description of the test") {
/* Put your testing code here. */
}

Take a look at the other tests provided to get a sense of how to write a test case. The EXPECT macro takes in two expressions. If those expressions are equal, great! Nothing happens. Otherwise, EXPECT reports an error. You can run the tests by choosing the “Run Tests” button from the demo app.

When you’re writing tests, be strategic about the tests you add. What are some tricky cases you might want to confirm work correctly? Are there any edge cases (extremely small cases, highly unusual cases, etc.) that would be worth testing?

Once you have everything working, run our demo program to play around with your code interactively. Then, if you like, leave an Only Connect puzzle of your own choosing! To do so, edit the file comments at the top of the file with the consonant string, along with a hint.

To summarize, here’s what you need to do:

  • Implement the onlyConnectize function in OnlyConnect.cpp. This function must be implemented recursively. It takes as input a string. The output should be that same string, in upper case, with all characters except consonants deleted. Feel free to write helper functions if you’d like.
  • Add at least one test case using the ADD_TEST macro. Your test should go in the file OnlyConnect.cpp, preferably with all the other test cases. For full credit, your test case should check some style of input that wasn’t previously addressed by the provided tests.

As you’re writing up your solution to this problem, remember that coding style is important. We have a style guide available on the BB website. Take a few minutes to read over it, then review your code to make sure it conforms to those style expectations.

Some notes on this problem:

  • All C++ programs begin inside the main() function, and we’ve already written this function for you in one of the starter files. You just need to implement onlyConnectize and are not responsible for writing main(). (In fact, if you did try to write your own main() function here, you’d get an error because there would be two different versions of main() and C++ wouldn’t know which one to pick!)
  • Your solution must be recursive. You may not use loops (while, for, do…while, or goto).
  • Make sure that you’re always returning a value from your recursive function. It’s easy to accidentally forget to do this when you’re getting started with recursion.
  • You can use toUpperCase from the “strlib.h” header to convert a single character to upper case. It takes in a char, then returns the upper-case version of that letter. If you call toUpperCase on a non-letter character like ‘$‘ or ‘*‘, it will return the original character unmodified.
  • The isalpha function from the <cctype> header takes in a character and returns whether it’s a letter. There is no library function that checks if a letter is a consonant or vowel, though.
  • If you’re coming from Python, note that C++ doesn’t have an in operator like the one in Python and that the and and or operators are denoted by && and ||, respectively. Check out the online “Python-to-C++ Guide” on the course website for more information.
  • Remember that C++ treats individual characters differently than strings. Individual characters have type char. To talk about a specific single character, you must use single quotes (e.g. ‘a’ rather than “a”). Strings have type string. To talk about a specific string, you must use double- quotes (e.g. “hello” rather than ‘hello’).
  • You can convert a char to a string by using the charToString function from “strlib.h“.
  • You are welcome to add your own helper functions when solving this problem. Those functions must obey the same rules of this problem as the main function (e.g. no loops) .
  • Just to make sure you didn’t miss this, we are treating the letter y as a vowel.
  • You shouldn’t need to edit OnlyConnect.h in the course of solving this problem.

问题分析与算法设计

递归的解决思路:

第一层分支:if(phrase.size()<=1)——判断是否达到递归出口

如果满足条件(达到出口):

为元音字母或为非字母字符——返回空,递归结束;否则返回相应大写辅音字母(string形式),递归结束

如果不满足条件(递归继续):

为元音字母或为非字母字符——返回onlyConnectize(phrase.substr(0,phrase.size()-1));否则返回onlyConnectize(phrase.substr(0,phrase.size()-1)) +string(1,toupper(phrase[phrase.size()-1])),递归继续

代码

/* File: OnlyConnect.cpp
 *
 * TODO: Edit these comments to describe anything interesting or noteworthy in your implementation.
 *
 * TODO: Edit these comments to leave a puzzle for your section leader to solve!
 */
#include "OnlyConnect.h"
#include <cctype>
using namespace std;

string onlyConnectize(string phrase) {
    string vowels="AEIOUaeiou";     // for check if vowel
    if(phrase.size()<=1){
        if(vowels.find(phrase)<vowels.size()||!isalpha(phrase[0])){
            return "";
        }else{
            return string(1,toupper(phrase[0]));
        }
    }else{
        if(vowels.find(phrase.substr(phrase.size()-1,1))<vowels.size()){
            return onlyConnectize(phrase.substr(0,phrase.size()-1));
        }else if(!isalpha(phrase[phrase.size()-1])){
            return onlyConnectize(phrase.substr(0,phrase.size()-1));
        }
        else{
            return onlyConnectize(phrase.substr(0,phrase.size()-1))
                    +string(1,toupper(phrase[phrase.size()-1]));
        }
    }
}


/* * * * * * Provided Test Cases * * * * * */
#include "GUI/SimpleTest.h"

PROVIDED_TEST("Handles single-character inputs.") {
    EXPECT_EQUAL(onlyConnectize("A"), "");
    EXPECT_EQUAL(onlyConnectize("Q"), "Q");
}

PROVIDED_TEST("Converts lower-case to upper-case.") {
    EXPECT_EQUAL(onlyConnectize("lowercase"), "LWRCS");
    EXPECT_EQUAL(onlyConnectize("uppercase"), "PPRCS");
}

/* TODO: You will need to add your own tests into this suite of test cases. Think about the sorts
 * of inputs we tested here, and, importantly, what sorts of inputs we *didn't* test here. Some
 * general rules of testing:
 *
 *    1. Try extreme cases. What are some very large cases to check? What are some very small cases?
 *
 *    2. Be diverse. There are a lot of possible inputs out there. Make sure you have tests that account
 *       for cases that aren't just variations of one another.
 *
 *    3. Be sneaky. Don't just try standard inputs. Try weird ones that you wouldn't expect anyone to
 *       actually enter, but which are still perfectly legal.
 *
 * Happy testing!
 */

STUDENT_TEST("Extreme test"){
    EXPECT_EQUAL(onlyConnectize("What's up,114514 1919810"), "WHTSP");
    EXPECT_EQUAL(onlyConnectize(""), "");
}

实验小结

1.在判断是否为元音字母时先规定了一个字符串string vowels=”AEIOUaeiou”,再结合find函数的返回值进行判断

2.需要考虑到非字母的特殊情况

3.需要考虑初始字符串长度小于1的情况(即空字符串)

Problem 5-Playing Fair

Consider the following scenarios:

  • Ten people want to play pick-up basketball. They select one person to captain team A and one to captain team B. The two captains then take turns choosing players for their team. One option would be to alternate between captains A and B, but that would give the team that picked first a noticeable advantage over the other. In what order should the captains pick players?
  • The World Chess Championship is a multi-game chess match held every two years between the reigning world champion and a challenger. In chess, white has a slight advantage over black, so both players should have an equal number of games as white and as black. However, if one player gets too many games as white early on, they might accumulate a score advantage early on that puts pressure on the other player. In what order should the players play as white and black?
  • In old-school NFL rules, if a postseason football game went to overtime, one team would get pos- session of the ball and be given a chance to score. If they scored, they’d instantly win the game. If they didn’t, the other team would get possession and a chance to score. If they didn’t, the first team would get another try, etc. This gives an advantage to whoever gets possession first. What’s a better way to decide which team gets a chance to score to make this as fair as possible?

These scenarios all have a core setup in common. There are two parties (we’ll call them A and B) who take turns at an activity that confers an advantage to whoever performs it. The goal is to determine the order in which A and B should perform that activity so as to make it as close to fair as possible.

There’s a clever recursive technique for addressing this problem that keeps the advantage of going first to a minimum. We’re going to consider two kinds of sequences: A-sequences and B-sequences, which each give a slight advantage to players A and B, respectively.

There are different A-sequences and B-sequences of different lengths. Each sequence is given a number called its order. The higher the order of the sequence, the more games are played. For example, here are the A and B sequences of orders 0, 1, 2, 3, and 4:

Order 0Order 1Order 2Order 3Order 4
A-sequence:AABABBAABBABAABABBABAABBAABABBA
B-sequence:BBABAABBAABABBABAABABBAABBABAAB

We can interpret these sequences as instructions of who gets to play when. For example, the A-sequence of order 2, ABBA, can be thought of as saying “A plays first, then B, then B again, then A again.” There’s a slight advantage to A going first, but it’s mitigated because B gets two turns in a row. The B-sequence of order three, BAABABBA, means “B takes a turn, then A, then A again, then B, then A, then B, then B again, then A.” If you think about what this looks like in practice, it means that B has a little advantage from going first, but the other alternations ensure that A gets to recoup some of that disadvantage later on.

Right now these sequences might look mysterious, but there’s a nice pattern. Take the A-sequence of order 4, ABBABAABBAABABBA, and split it in half down the middle, as shown to the right. That gives back the two se- quences ABBABAAB and BAABABBA. If we look in the table shown above, we can see that this first sequence is the A-sequence of order 3, and the second sequence is the B-sequence of order 3. Interesting!

Similarly, look at what happens when you split the B-sequence of order 3,

BAABABBA, in half. That gives back BAAB and ABBA. And again, if we look in our table, we see that this first string is the B-sequence of order 2 and the second is the A-sequence of order 2. Nifty!

More generally, the pattern looks like this: if you take an A-sequence of order n (where n > 0) and split it in half, you get back an A-sequence of order n – 1 followed by a B-sequence of order n – 1. Similarly, if you take a B-sequence of order n (with n > 0) and split it in half, you get a B-sequence of order n – 1 fol- lowed by an A-sequence of order n – 1. This process stops when you need to form the A-sequence or B- sequence of order 0, which are just A and B, respectively.

Using these observations, implement a pair of functions

string aSequenceOfOrder(int n);
string bSequenceOfOrder(int n);

that take as input a number n ≥ 0, then return the A-sequence and B-sequence of order n, respectively. As with the Only Connect problem, these functions must be recursive and must not use loops.

If someone calls either function passing in a negative value of n, you should use the error function from the header “error.h” to report an error. You call this function by writing

error("a string containing your error message");

The error function immediately jumps out of the function to say that something terrible has happened.

We’ve included some tests you can use to check your solution, but they aren’t exhaustive. You’ll need to add at least one custom test case, and ideally more. You might notice that we’ve used the EXPECT_ERROR macro in one of our test cases. This macro evaluates the expression and sees whether it calls the error() function to report an error. If so, great! It makes a note that an error was indeed generated. If not, it causes the test to fail and reports that the expression failed to trigger an error.

The starter code contains a demo of another property of these sequences. Imagine you’re in an open field. You then read the characters of an A-sequence from left to right. Whenever you read an A, you take a step forward, then rotate 60°. Every time you read a B, you turn around without moving. Repeating this process gives an intricate and complex result. Once your code is working, run our demo app to see what it is! The slider at the bottom controls the order of the sequence.

To summarize, here’s what you need to do:

  • Implement the aSequenceOfOrder and bSequenceOfOrder functions in the file PlayingFair.cpp. These functions should return an A-sequence and B-sequence of order n, respec- tively. These functions must be implemented recursively. If either function receives a nega- tive number as an input, they should use the error() function to report an error.  As you go, test your code by using the “Run Tests” button in the provided program.
  • Add at least one test case using the STUDENT_TEST macro. Your test should go in the file PlayingFair.cpp, preferably with all the other test cases. For full credit, your test case should try to check some case that wasn’t previously addressed by the bundled tests.
  • Once everything works, click the “Playing Fair” button in the demo program to see a cool visualization of the sequences you’ve generated.

Some notes on this problem:

  • As with most recursive functions, you probably shouldn’t need to write much total code here. If you’ve written thirty or more lines of code and are struggling to get things working, you may be missing an easier solution route and might want to check in with your TA for advice.
  • An A-sequence of order n has length 2n, which means that the lengths of these sequences grow extremely rapidly as a function of n. For reference, an order-30 A-sequence will be over a billion characters long, and an order-300 A-sequence has more characters than there are atoms in the observable universe. Don’t worry about generating sequences of those sorts of orders; stick with low- order sequences, say, with n ≤ 20.
  • If your code isn’t working, step through it in the debugger! You saw how to step through code in Assignment 0.
  • Testing is key here. The tests we’ve provided aren’t sufficient to cover all the cases that might come up. You’re required to add at least one test case, and really do take that seriously. If you’re trying to test something recursive, what sorts of cases might be good to check?
  • You shouldn’t need to edit PlayingFair.h in the course of solving this problem.

问题分析与算法设计

由题目给出的样例可以看最终返回字符串的前一半与后一半A与B互相替换,由此可以得出递归思路:

先设计一个函数aExb(string str)用于交换AB(同样用递归实现),在递归出口时(长度为1)直接返回对应交换结果,否则返回return aExb(str.substr(0,1))+aExb(str.substr(1,str.size()-1));

再设计主递归函数,以aSequenceOfOrder(int n)为例在递归出口时(n为0)return “A”,否则return aSequenceOfOrder(n-1)+aExb(aSequenceOfOrder(n-1));。bSequenceOfOrder(int n)同理。

代码

/*
 * File: PlayingFair.cpp
 */
#include "PlayingFair.h"
#include "error.h"
#include <string>
using namespace std;

string aExb(string str){
    if(str=="A"){
        return "B";
    }else if(str=="B"){
        return "A";
    }else{
        return aExb(str.substr(0,1))+aExb(str.substr(1,str.size()-1));
    }
}

string aSequenceOfOrder(int n) {
    if(n==0){
        return "A";
    }else if(n>0){
        return aSequenceOfOrder(n-1)+aExb(aSequenceOfOrder(n-1));
    }else{
        error("a string containing your error message");
    }
}

string bSequenceOfOrder(int n) {
    if(n==0){
        return "B";
    }else if(n>0){
        return bSequenceOfOrder(n-1)+aExb(bSequenceOfOrder(n-1));
    }else{
        error("a string containing your error message");
    }
}

/* * * * * * Tests Below This Point * * * * * */
#include "GUI/SimpleTest.h"

PROVIDED_TEST("Sequences of order 3 are correct.") {
    /* Some very basic checks. */
    EXPECT_EQUAL(aSequenceOfOrder(3), "ABBABAAB");
    EXPECT_EQUAL(bSequenceOfOrder(3), "BAABABBA");
}

PROVIDED_TEST("Triggers error on negative inputs.") {
    /* The EXPECT_ERROR macro expects the given expression to call error(). Remember that
     * you need to guard against invalid inputs.
     */
    EXPECT_ERROR(aSequenceOfOrder(-137));
    EXPECT_ERROR(bSequenceOfOrder(-137));
}

STUDENT_TEST("Sequences of order 4 are correct.") {
    /* Some very basic checks. */
    EXPECT_EQUAL(aSequenceOfOrder(4), "ABBABAABBAABABBA");
    EXPECT_EQUAL(bSequenceOfOrder(4), "BAABABBAABBABAAB");
}

实验小结

1.需要在递归时预留异常情况的处理(n<0)

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇