2024年12月完成(补充提交)

This commit is contained in:
Cx330 committed 2025-03-29 23:02:48 +08:00
commit 4e2bf47db0
39 files changed
+2106

No files matched your search

+251
View File
@@ -0,0 +1,251 @@
#ifdef _MSC_VER
#pragma warning(disable:4503) // `silence compiler complaints about generated names being too long'
#endif
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>
#include "split.h"
#include <time.h>
using std::istream; using std::cin;
using std::copy; using std::cout;
using std::endl; using std::find;
using std::getline; using std::logic_error;
using std::map; using std::string;
using std::vector; using std::domain_error;
using std::rand;
typedef vector<string> Rule;
typedef vector<Rule> Rule_collection;
typedef map<string, Rule_collection> Grammar;
// read a grammar from a given input stream
Grammar read_grammar(istream& in)
{
Grammar ret;
string line;
// read the input
while (getline(in, line)) {
// `split' the input into words
vector<string> entry = split(line);
if (!entry.empty())
// use the category to store the associated rule
ret[entry[0]].push_back(
Rule(entry.begin() + 1, entry.end()));
}
return ret;
}
void gen_aux(const Grammar&, const string&, vector<string>&);
int nrand(int);
vector<string> gen_sentence(const Grammar& g)
{
vector<string> ret;
gen_aux(g, "<sentence>", ret);
return ret;
}
bool bracketed(const string& s)
{
return s.size() > 1 && s[0] == '<' && s[s.size() - 1] == '>';
}
void
gen_aux(const Grammar& g, const string& word, vector<string>& ret)
{
if (!bracketed(word)) {
ret.push_back(word);
} else {
// locate the rule that corresponds to `word'
Grammar::const_iterator it = g.find(word);
if (it == g.end())
throw logic_error("empty rule");
// fetch the set of possible rules
const Rule_collection& c = it->second;
// from which we select one at random
const Rule& r = c[nrand(c.size())];
// recursively expand the selected rule
for (Rule::const_iterator i = r.begin(); i != r.end(); ++i)
gen_aux(g, *i, ret);
}
}
int main()
{
// generate the sentence
vector<string> sentence = gen_sentence(read_grammar(cin));
// write the first word, if any
#ifdef _MSC_VER
std::vector<string>::const_iterator it = sentence.begin();
#else
vector<string>::const_iterator it = sentence.begin();
#endif
if (!sentence.empty()) {
cout << *it;
++it;
}
// write the rest of the words, each preceded by a space
while (it != sentence.end()) {
cout << " " << *it;
++it;
}
cout << endl;
return 0;
}
// return a random integer in the range `[0,' `n)'
int nrand(int n)
{
if (n <= 0 || n > RAND_MAX)
throw domain_error("Argument to nrand is out of range");
const int bucket_size = RAND_MAX / n;
int r;
do r = rand() / bucket_size;
while (r >= n);
return r;
}
#ifdef _MSC_VER
#pragma warning(disable:4503) // 关闭编译器警告,避免对生成的名称过长的抱怨
#endif
#include <algorithm> // 引入算法库,提供常用的算法
#include <cstdlib> // 引入C标准库,包含rand()函数
#include <iostream> // 引入标准输入输出流库
#include <map> // 引入映射容器(map)库
#include <stdexcept> // 引入标准异常库,提供逻辑错误和域错误等异常
#include <string> // 引入字符串库
#include <vector> // 引入动态数组(vector)库
#include "split.h" // 引入自定义的split.h头文件(假定提供了字符串拆分功能)
#include <time.h> // 引入时间库,支持随机数生成
using std::istream; using std::cin;
using std::copy; using std::cout;
using std::endl; using std::find;
using std::getline; using std::logic_error;
using std::map; using std::string;
using std::vector; using std::domain_error;
using std::rand; // 引入rand函数
// 定义规则(字符串集合)和语法(规则集合)的类型
typedef vector<string> Rule; // 一个规则是字符串的集合
typedef vector<Rule> Rule_collection; // 规则集合是规则的集合
typedef map<string, Rule_collection> Grammar; // 语法是一个映射:类别 -> 规则集合
// 从输入流中读取语法并返回
Grammar read_grammar(istream& in) {
Grammar ret; // 用于存储语法
string line;
// 持续读取每一行
while (getline(in, line)) {
// 将当前行拆分成单词
vector<string> entry = split(line);
// 如果拆分出的单词不为空,则根据类别存储规则
if (!entry.empty())
ret[entry[0]].push_back(
Rule(entry.begin() + 1, entry.end())); // 使用类别作为key,规则作为value
}
return ret; // 返回语法
}
// 递归生成句子的辅助函数
void gen_aux(const Grammar&, const string&, vector<string>&);
// 返回一个范围在[0, n)内的随机整数
int nrand(int);
// 生成一个句子,调用gen_aux进行递归生成
vector<string> gen_sentence(const Grammar& g) {
vector<string> ret;
gen_aux(g, "<sentence>", ret); // 从<sentence>开始生成句子
return ret;
}
// 判断一个字符串是否是被尖括号包围的
bool bracketed(const string& s) {
return s.size() > 1 && s[0] == '<' && s[s.size() - 1] == '>';
}
// 递归地生成句子中的一部分
void gen_aux(const Grammar& g, const string& word, vector<string>& ret) {
if (!bracketed(word)) {
ret.push_back(word); // 如果不是被尖括号包围的单词,直接加入句子
}
else {
// 查找对应的规则
Grammar::const_iterator it = g.find(word);
if (it == g.end()) // 如果没有找到规则,抛出异常
throw logic_error("empty rule");
// 获取该单词的规则集合
const Rule_collection& c = it->second;
// 从规则集合中随机选择一个规则
const Rule& r = c[nrand(c.size())];
// 对选中的规则中的每个单词进行递归处理
for (Rule::const_iterator i = r.begin(); i != r.end(); ++i)
gen_aux(g, *i, ret);
}
}
int main() {
// 生成句子
vector<string> sentence = gen_sentence(read_grammar(cin));
// 输出第一个单词(如果有)
vector<string>::const_iterator it = sentence.begin();
if (!sentence.empty()) {
cout << *it;
++it;
}
// 输出剩余的单词,每个单词前加一个空格
while (it != sentence.end()) {
cout << " " << *it;
++it;
}
cout << endl; // 输出换行
return 0;
}
// 返回一个随机整数,范围在[0, n)
int nrand(int n) {
if (n <= 0 || n > RAND_MAX)
throw domain_error("Argument to nrand is out of range");
const int bucket_size = RAND_MAX / n; // 将随机数均匀分布
int r;
// 确保随机数在有效范围内
do r = rand() / bucket_size;
while (r >= n);
return r;
}
+43
View File
@@ -0,0 +1,43 @@
#include <cctype>
#include <string>
#include <vector>
#include "split.h"
using std::vector;
using std::string;
#ifndef _MSC_VER
using std::isspace;
#endif
vector<string> split(const string& s)
{
vector<string> ret;
typedef string::size_type string_size;
string_size i = 0;
// invariant: we have processed characters `['original value of `i', `i)'
while (i != s.size()) {
// ignore leading blanks
// invariant: characters in range `['original `i', current `i)' are all spaces
while (i != s.size() && isspace(s[i]))
++i;
// find end of next word
string_size j = i;
// invariant: none of the characters in range `['original `j', current `j)' is a space
while (j != s.size() && !isspace(s[j]))
++j;
// if we found some nonwhitespace characters
if (i != j) {
// copy from `s' starting at `i' and taking `j' `\-' `i' chars
ret.push_back(s.substr(i, j - i));
i = j;
}
}
return ret;
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef GUARD_split_h
#define GUARD_split_h
#include <vector>
#include <string>
std::vector<std::string> split(const std::string&);
#endif
@@ -0,0 +1,108 @@
#include <algorithm>
#include <string>
#include <vector>
#include "pics.h"
using std::string;
using std::vector;
using std::max;
#ifdef _MSC_VER
//#include "../minmax.h"
#else
//using std::max;
#endif
string::size_type width(const vector<string>& v)
{
string::size_type maxlen = 0;
#ifdef _MSC_VER
for(std::vector<string>::size_type i = 0; i != v.size(); ++i)
#else
for(vector<string>::size_type i = 0; i != v.size(); ++i)
#endif
maxlen = max(maxlen, v[i].size());
return maxlen;
}
vector<string> frame(const vector<string>& v)
{
vector<string> ret;
string::size_type maxlen = width(v);
string border(maxlen + 4, '*');
// write the top border
ret.push_back(border);
// write each interior row, bordered by an asterisk and a space
#ifdef _MSC_VER
for (std::vector<string>::size_type i = 0; i != v.size(); ++i) {
#else
for (vector<string>::size_type i = 0; i != v.size(); ++i) {
#endif
ret.push_back("* " + v[i] +
string(maxlen - v[i].size(), ' ') + " *");
}
// write the bottom border
ret.push_back(border);
return ret;
}
vector<string> vcat(const vector<string>& top,
const vector<string>& bottom)
{
// copy the `top' picture
vector<string> ret = top;
// copy entire `bottom' picture
#ifdef _MSC_VER
for (std::vector<string>::const_iterator it = bottom.begin();
#else
for (vector<string>::const_iterator it = bottom.begin();
#endif
it != bottom.end(); ++it)
ret.push_back(*it);
return ret;
}
vector<string>
hcat(const vector<string>& left, const vector<string>& right)
{
vector<string> ret;
// add 1 to leave a space between pictures
string::size_type width1 = width(left) + 1;
// indices to look at elements from `left' and `right' respectively
#ifdef _MSC_VER
std::vector<string>::size_type i = 0, j = 0;
#else
vector<string>::size_type i = 0, j = 0;
#endif
string s;
// continue until we've seen all rows from both pictures
while (i != left.size() || j != right.size()) {
// construct new `string' to hold characters from both pictures
//string s;
// copy a row from the left-hand side, if there is one
if (i != left.size())
s = left[i++];
// pad to full width
s += string(width1 - s.size(), ' ');
// copy a row from the right-hand side, if there is one
if (j != right.size())
s += right[j++];
// add `s' to the picture we're creating
ret.push_back(s);
}
return ret;
}
@@ -0,0 +1,17 @@
#ifndef GUARD_pics_h
#define GUARD_pics_h
#include <string>
#include <vector>
std::string::size_type width(const std::vector<std::string>& v);
std::vector<std::string> frame(const std::vector<std::string>& v);
std::vector<std::string> vcat(const std::vector<std::string>& top,
const std::vector<std::string>& bottom);
std::vector<std::string> hcat(const std::vector<std::string>& left,
const std::vector<std::string>& right);
#endif
@@ -0,0 +1,85 @@
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include "pics.h"
using std::cout;
using std::copy;
using std::endl;
using std::ostream_iterator;
using std::string;
using std::vector;
int main()
{
vector<string> p;
p.push_back("this is an");
p.push_back("example");
p.push_back("to");
p.push_back("illustrate");
p.push_back("framing");
ostream_iterator<string>ofile(cout, "\n");
copy(p.begin(), p.end(), ofile);
cout << endl;
vector<string> f = frame(p);
copy(f.begin(), f.end(), ofile); cout << endl;
vector<string> h = hcat(p,frame(p));
copy(h.begin(), h.end(), ofile);
cout << endl;
return 0;
}
#include <algorithm> // 引入算法库,提供常用的算法
#include <iostream> // 引入标准输入输出流库
#include <iterator> // 引入迭代器库
#include <string> // 引入字符串库
#include <vector> // 引入动态数组(vector)库
#include "pics.h" // 引入自定义的 pics.h 库(假设此库包含框架生成和拼接相关的功能)
using std::cout; // 使用标准输出流
using std::copy; // 引入copy算法
using std::endl; // 引入换行符
using std::ostream_iterator; // 引入输出流迭代器,用于输出容器的内容
using std::string; // 使用字符串类型
using std::vector; // 使用vector容器
int main() {
// 创建一个vector<string>类型的容器 p,存储字符串
vector<string> p;
p.push_back("this is an"); // 添加一个字符串
p.push_back("example"); // 添加一个字符串
p.push_back("to"); // 添加一个字符串
p.push_back("illustrate"); // 添加一个字符串
p.push_back("framing"); // 添加一个字符串
// 创建输出流迭代器,指定输出到 cout,并且每个元素输出后换行
ostream_iterator<string> ofile(cout, "\n");
// 使用copy算法,将vector p中的内容逐个输出
copy(p.begin(), p.end(), ofile);
cout << endl; // 输出换行符
// 对vector p应用框架操作,生成一个新的vector f
vector<string> f = frame(p);
// 使用copy算法,将vector f中的内容逐个输出
copy(f.begin(), f.end(), ofile);
cout << endl; // 输出换行符
// 将vector p和vector f进行横向拼接,生成一个新的vector h
vector<string> h = hcat(p, frame(p));
// 使用copy算法,将vector h中的内容逐个输出
copy(h.begin(), h.end(), ofile);
cout << endl; // 输出换行符
return 0; // 程序正常结束
}
+145
View File
@@ -0,0 +1,145 @@
#include <map>
#include <iostream>
#include <string>
#include <vector>
#include "split.h"
using std::cin; using std::cout;
using std::endl; using std::getline;
using std::istream; using std::string;
using std::vector; using std::map;
// find all the lines that refer to each word in the input
map<string, vector<int> >
xref(istream& in,
vector<string> find_words(const string&) = split)
{
string line;
int line_number = 0;
map<string, vector<int> > ret;
// read the next line
while (getline(in, line)) {
++line_number;
// break the input line into words
vector<string> words = find_words(line);
// remember that each word occurs on the current line
#ifdef _MSC_VER
for (std::vector<string>::const_iterator it = words.begin();
#else
for (vector<string>::const_iterator it = words.begin();
#endif
it != words.end(); ++it)
ret[*it].push_back(line_number);
}
return ret;
}
int main()
{
// call `xref' using `split' by default
map<string, vector<int> > ret = xref(cin);
// write the results
#ifdef _MSC_VER
for (std::map<string, vector<int> >::const_iterator it = ret.begin();
#else
for (map<string, vector<int> >::const_iterator it = ret.begin();
#endif
it != ret.end(); ++it) {
// write the word
cout << it->first << " occurs on line(s): ";
// followed by one or more line numbers
#ifdef _MSC_VER
std::vector<int>::const_iterator line_it = it->second.begin();
#else
vector<int>::const_iterator line_it = it->second.begin();
#endif
cout << *line_it; // write the first line number
++line_it;
// write the rest of the line numbers, if any
while (line_it != it->second.end()) {
cout << ", " << *line_it;
++line_it;
}
// write a new line to separate each word from the next
cout << endl;
}
return 0;
}
#include <map> // 引入 map 容器,用于存储每个单词及其出现的行号
#include <iostream> // 引入标准输入输出流库
#include <string> // 引入字符串库
#include <vector> // 引入动态数组库,用于存储每一行的单词
#include "split.h" // 引入自定义的 split.h 库,假设包含用于分割字符串的函数
using std::cin; // 使用标准输入流
using std::cout; // 使用标准输出流
using std::endl; // 使用换行符
using std::getline; // 使用getline函数读取整行输入
using std::istream; // 使用输入流
using std::string; // 使用字符串类型
using std::vector; // 使用vector容器
using std::map; // 使用map容器
// xref函数:用来查找每个单词在文本中出现的行号
// 参数:输入流 in 和一个函数指针 find_words,用于分割每行的单词(默认为 split 函数)
map<string, vector<int> >
xref(istream& in,
vector<string> find_words(const string&) = split)
{
string line; // 用来存储每一行的文本
int line_number = 0; // 行号
map<string, vector<int> > ret; // 用map来存储每个单词及其对应的行号
// 按行读取输入
while (getline(in, line)) {
++line_number; // 增加行号
// 调用find_words函数将一行文本分割成单词
vector<string> words = find_words(line);
// 将当前行号添加到每个单词的对应位置
for (vector<string>::const_iterator it = words.begin(); it != words.end(); ++it)
ret[*it].push_back(line_number); // 将单词和行号对应起来
}
return ret; // 返回包含每个单词及其行号的map
}
int main()
{
// 调用 xref 函数,默认使用 split 来分割单词
map<string, vector<int> > ret = xref(cin);
// 输出结果
for (map<string, vector<int> >::const_iterator it = ret.begin(); it != ret.end(); ++it) {
// 输出单词
cout << it->first << " occurs on line(s): ";
// 获取并输出单词出现的行号
vector<int>::const_iterator line_it = it->second.begin();
cout << *line_it; // 输出第一个行号
++line_it;
// 输出其余的行号
while (line_it != it->second.end()) {
cout << ", " << *line_it;
++line_it;
}
// 换行
cout << endl;
}
return 0; // 程序结束
}
+43
View File
@@ -0,0 +1,43 @@
#include <cctype>
#include <string>
#include <vector>
#include "split.h"
using std::vector;
using std::string;
#ifndef _MSC_VER
using std::isspace;
#endif
vector<string> split(const string& s)
{
vector<string> ret;
typedef string::size_type string_size;
string_size i = 0;
// invariant: we have processed characters `['original value of `i', `i)'
while (i != s.size()) {
// ignore leading blanks
// invariant: characters in range `['original `i', current `i)' are all spaces
while (i != s.size() && isspace(s[i]))
++i;
// find end of next word
string_size j = i;
// invariant: none of the characters in range `['original `j', current `j)' is a space
while (j != s.size() && !isspace(s[j]))
++j;
// if we found some nonwhitespace characters
if (i != j) {
// copy from `s' starting at `i' and taking `j' `\-' `i' chars
ret.push_back(s.substr(i, j - i));
i = j;
}
}
return ret;
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef GUARD_split_h
#define GUARD_split_h
#include <vector>
#include <string>
std::vector<std::string> split(const std::string&);
#endif