2024年12月完成(补充提交)
This commit is contained in:
commit
4e2bf47db0
39 files changed
+2106
No files matched your search
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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; // 程序正常结束
|
||||
}
|
||||
Reference in new issue
Block a user