文章目录
1
1.1 统计单词个数
//统计单词个数
#include <iostream>
#include <map>
#include <string>
using std::cin; using std::cout;
using std::endl;
using std::map; using std::string;
int main(int argc, char const *argv[]){
string s;
map<string, int>counters;
while(cin >> s)
++counters[s];
for (map<string,int>::const_iterator it = counters.begin(); it != counters.end(); ++it) {
cout << it->first <<"\t" << it->second <<endl;
}
return 0;
}
1.2 统计单词出现的行数
//统计单词出现的行数
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <cctype>
using std::cin; using std::cout;
using std::endl;
using std::map; using std::string;
using std::vector; using std::istream;
//是空白区域为true
bool space(char c){
return isspace(c);
}
//不是空白区域为true
bool not_space(char c){
return !isspace(c);
}
vector<string> split(const string& str){
typedef string::const_iterator iter;
vector<string> ret;
iter i = str.begin();
while(i != str.end()){
//忽略前面的空白
i = find_if(i, str.end(), not_space);
//找到下一个单词的结尾
iter j = find_if(i , str.end(), space);
//复制在[i,j)中的字符
if(i != str.end()){
ret.push_back(string(i, j));
}
i = j;
}
return ret;
}
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;
while(getline(in, line)){
++line_number;
vector<string> words = find_words(line);
for (vector<string>::const_iterator it = words.begin(); it != words.end(); ++it) {
vector<int>::const_iterator it2;
for (it2 = ret[*it].begin(); it2 != ret[*it].end(); ++it2) {
if(*it2 == line_number){
break;
}
}
if(it2 == ret[*it].end()){
ret[*it].push_back(line_number);
}
}
}
return ret;
}
int main(int argc, char const *argv[]){
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;
}
1.3 造句
//造句
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <cctype>
#include <stdexcept>
#include <cstdlib>
using std::cin; using std::cout;
using std::endl;
using std::map; using std::string;
using std::vector; using std::istream;
using std::logic_error;
using std::domain_error;
typedef vector<string> Rule;
typedef vector<Rule> Rule_collection;
typedef map<string, Rule_collection> Grammar;
//是空白区域为true
bool space(char c){
return isspace(c);
}
//不是空白区域为true
bool not_space(char c){
return !isspace(c);
}
vector<string> split(const string& str){
typedef string::const_iterator iter;
vector<string> ret;
iter i = str.begin();
while(i != str.end()){
//忽略前面的空白
i = find_if(i, str.end(), not_space);
//找到下一个单词的结尾
iter j = find_if(i , str.end(), space);
//复制在[i,j)中的字符
if(i != str.end()){
ret.push_back(string(i, j));
}
i = j;
}
return ret;
}
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()));
}
}
return ret;
}
bool backeted(const string& s){
return s.size() > 1 && s[0] == '<' && s[s.size() - 1] == '>';
}
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;
}
void gen_aux(const Grammar& g, const string& word, vector<string>& ret){
if(!backeted(word)){
ret.push_back(word);
}else{
//为对应的word规则定位
Grammar::const_iterator it = g.find(word);
if(it == g.end()){
throw logic_error("empty rule");
}
//获取可能的规则
const Rule_collection& c = it->second;//进入到vector<vector<string>>
//从规则集合中随机选择一条规则
const Rule& r = c[nrand(c.size())];//到vector<string>
for (Rule::const_iterator i = r.begin(); i != r.end(); ++i) {
gen_aux(g, *i, ret);
}
}
}
vector<string> gen_sentence(const Grammar& g){
vector<string> ret;
//展开第二个参数传递过来的字符串
//在第一个参数的文法(语句结构)中查找这个字符串并将它的输出放在第三个参数中
gen_aux(g, "<sentence>", ret);
return ret;
}
int main(int argc, char const *argv[]){
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;
}
/*
<sentence> the <nm> <v> <p>
<nm> <n>
<nm> <a> <nm>
<n> cat
<n> dog
<a> large
<a> absurd
<v> sits
<v> jumps
<p> on te stairs
<p> under the sky
*/
1 桉单词出现的次数从小到大输出单词
1.1 法一
#include <iostream>
using std::cin; using std::cout;
using std::endl;
#include <string>
using std::string;
#include <map>
using std::map;
#include <vector>
using std::vector;
#include <cstddef>
using std::size_t ;
int main(int argc, char **argv){
string s;
map<string, int> counters;
vector<string> wordSet[100];
size_t maxcount = 1;
while(cin >> s){
++counters[s];
wordSet[counters[s]].push_back(s);
if(counters[s] > maxcount) maxcount = counters[s];
}
for (vector<string>::size_type i = 1; i != maxcount; ++i) {
for (vector<string>::size_type j = 0; j != wordSet[i].size(); ++j) {
if(j != 0) cout << " ";
cout << wordSet[i][j];
}
if(wordSet[i].size() != 0) cout <<endl;
}
return 0;
}
1.2 法二
先用map<sring,int>映射表统计单词出现的次数,然后把map的数组转换成pair<int,string>存入multimap(一个键可以对应多个值)中,然后输出。
#include <iostream>
using std::cin; using std::cout;
using std::endl;
using std::istream;
using std::ostream;
#include <string>
using std::string;
#include <map>
using std::map;
using std::multimap;
#include <algorithm>
using std::transform;
#include <iterator>
using std::inserter;
#include <utility>
using std::pair;
pair<int, string> deal_pair(pair<string, int> p){
return pair<int, string > (p.second, p.first);
}
istream& counters_sort(istream& is, ostream& os){
string s;
map<string, int> counters;
multimap<int, string> ans;
while(cin >> s){
++counters[s];
}
//对counters数组按值从小到大排序
transform(counters.begin(), counters.end(), inserter(ans, ans.begin()), deal_pair);
for (multimap<int, string>::const_iterator it = ans.begin(); it != ans.end() ; ++it) {
os << it->second << "\t" << it->first <<endl;
}
return is;
}
int main(int argc, char **argv){
if(counters_sort(cin, cout)){
return 0;
}else{
return 1;
}
}
2 按分数评出等级
头文件:
Student_info.h
#ifndef ACM_Student_info
#define ACM_Student_info
#include <iostream>
#include <string>
#include <vector>
struct Student_info{
std::string name;
double midterm, final;
std::vector<double> homework;
};
bool compare(const Student_info&, const Student_info&);
std::istream& read_hw(std::istream&, std::vector<double>&);
std::istream& read(std::istream&, Student_info&);
#endif
grade.h
#ifndef ACM_GRADE_H
#define ACM_GRADE_H
#include<vector>
#include"Student_info.h"
double grade(double, double, double);
double grade(double, double, const std::vector<double>&);
double grade(const Student_info&);
#endif
#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
#include "grade.h"//grade函数重载声明
#include "Student_info.h"//与Student_info结构和相关的函数组装起来
#include <map>
#include <fstream>
using std::cin; using std::setprecision;
using std::cout; using std::sort;
using std::domain_error; using std::streamsize;
using std::string; using std::vector;
using std::max; using std::endl;
using std::istream;
//按照字母顺序排列学生
bool compare(const Student_info& x, const Student_info& y){
return x.name < y.name;
}
//求中位数
double median(vector<double> vec){
typedef vector<double>::size_type vec_sz;
vec_sz size = vec.size();
if(size == 0)
throw domain_error ("median of an empty vector");
sort(vec.begin(), vec.end());
vec_sz mid = size/2;
return size % 2 == 0 ? (vec[mid] + vec[mid-1])/2 : vec[mid];
}
//对Stundet_info类型的对象进行处理
double grade(const Student_info& s){
return grade(s.midterm, s.final, s.homework);//调用grade2
}//grade1
//根据期中、期末以及保存家庭作业的向量来计算学生的总成绩
double grade(double midterm, double final, const vector<double>& hw){
if(hw.size() == 0)
throw domain_error("student has done no homework");
return grade(midterm, final, median(hw));//如果家庭作业非空,则调用grade3
}//grade2
//根据期中、期末、平时成绩计算总成绩
double grade(double midterm, double final, double homework){
return 0.2 * midterm + 0.4 * final + 0.4 * homework;
}//garde3
//读入学生姓名、期中、期末成绩、家庭作业成绩
istream& read(istream& is, Student_info& s){
is >> s.name >> s.midterm >> s.final;
//如果输入的期中、期末成绩不是数字,则会把输入流标记为失败状态
read_hw(is, s.homework);//读入家庭作业
return is;
}
//从输入流中将家庭作业的成绩读入到一个vector<double>中
istream& read_hw(istream& in, vector<double>& hw){
if(in){//当前学生的姓名、期中期末成绩非法时(输入流标记为失败状态),不会读入家庭作业
//清除原先内容
hw.clear();//清除之前可能存在的成绩,重新再次拥有空向量
double x;
while(in >> x){//输入的不是成绩时,库把输入流标记为失败状态
hw.push_back(x);
}
//清除流使得输入动作对下个学生有效
in.clear();//清除所有错误标记使得输入动作可以继续,并不清除下一个存储在输入流中的姓名
}//如正常读完in,则返回in正确标记
return in;
}
int main(){
vector<Student_info> students;
Student_info record;
string::size_type maxlen = 0;//最长姓名的长度
string file = "/Users/macbookpro/CLionProjects/ACM/students10000.txt";
std::ifstream infile;
infile.open(file);
//读入并存储所有学生的数据
while(read(infile,record)){//遇到非法输入,则结束输入,例如读入两个姓名
//找出最长姓名的长度
maxlen = max(maxlen, record.name.size());
students.push_back(record);
}
infile.close();
infile.clear();
//按字母顺序排列学生记录
sort(students.begin(), students.end(), compare);
//统计不同等级的学生个数
std::map<string, int> counters;
//输出学生姓名和成绩
for (vector<Student_info>::size_type i = 0; i != students.size() ; ++i) {
//输出姓名,将姓名填充值maxlen+1个字符的长度
cout << students[i].name
<< string(maxlen + 1 - students[i].name.size(),' ');
//计算并输出成绩
try {
double final_grade = grade(students[i]);//调用grade2
if(final_grade >= 90.0){
counters["A"]++;
}else if(final_grade >= 80.0 && final_grade < 90.0){
counters["B"]++;
}else if(final_grade >= 70.0 && final_grade < 80.0){
counters["C"]++;
}else if(final_grade >= 60.0 && final_grade < 70.0){
counters["D"]++;
}else{
counters["F"]++;
}
streamsize pre = cout.precision();
cout << setprecision(3) << final_grade
<< setprecision(pre);
}catch (domain_error e){
cout << e.what();
}
cout << endl;
}
for (std::map<string, int>::const_iterator it = counters.begin(); it != counters.end() ; ++it) {
cout << it->first << "\t" << it->second <<endl;
}
return 0;
}
3 单词在同一行出现多次,只插入这个行编号一次
3.1 法一
//统计单词出现的行数
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <cctype>
using std::cin; using std::cout;
using std::endl;
using std::map; using std::string;
using std::vector; using std::istream;
//是空白区域为true
bool space(char c){
return isspace(c);
}
//不是空白区域为true
bool not_space(char c){
return !isspace(c);
}
vector<string> split(const string& str){
typedef string::const_iterator iter;
vector<string> ret;
iter i = str.begin();
while(i != str.end()){
//忽略前面的空白
i = find_if(i, str.end(), not_space);
//找到下一个单词的结尾
iter j = find_if(i , str.end(), space);
//复制在[i,j)中的字符
if(i != str.end()){
ret.push_back(string(i, j));
}
i = j;
}
return ret;
}
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;
while(getline(in, line)){
++line_number;
vector<string> words = find_words(line);
for (vector<string>::const_iterator it = words.begin(); it != words.end(); ++it) {
vector<int>::const_iterator it2;
//边面一行出现的同一个单词,输出多次
for (it2 = ret[*it].begin(); it2 != ret[*it].end(); ++it2) {
if(*it2 == line_number){
break;
}
}
if(it2 == ret[*it].end()){
ret[*it].push_back(line_number);
}
}
}
return ret;
}
int main(int argc, char const *argv[]){
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;
}
3.2 法二
//统计单词出现的行数
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <cctype>
#include <iterator>
using std::distance;
#include <algorithm>
using std::unique;
using std::cin; using std::cout;
using std::endl;
using std::map; using std::string;
using std::vector; using std::istream;
//是空白区域为true
bool space(char c){
return isspace(c);
}
//不是空白区域为true
bool not_space(char c){
return !isspace(c);
}
vector<string> split(const string& str){
typedef string::const_iterator iter;
vector<string> ret;
iter i = str.begin();
while(i != str.end()){
//忽略前面的空白
i = find_if(i, str.end(), not_space);
//找到下一个单词的结尾
iter j = find_if(i , str.end(), space);
//复制在[i,j)中的字符
if(i != str.end()){
ret.push_back(string(i, j));
}
i = j;
}
return ret;
}
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;
while(getline(in, line)) {
++line_number;
vector<string> words = find_words(line);
//法一
// for (vector<string>::const_iterator it = words.begin(); it != words.end(); ++it) {
// vector<int>::const_iterator it2;
// //边面一行出现的同一个单词,输出多次
// for (it2 = ret[*it].begin(); it2 != ret[*it].end(); ++it2) {
// if(*it2 == line_number){
// break;
// }
// }
// if(it2 == ret[*it].end()){
// ret[*it].push_back(line_number);
// }
//
// }
// }
//法二
for (vector<string>::const_iterator it = words.begin(); it != words.end(); ++it) {
ret[*it].push_back(line_number);
}
//unique:是把重复的元素移到后面去了,然后返回不重复元素的最后一个的迭代器
//resize:截断向量长度
//distance:返回区间长度
for (map<string, vector<int>>::iterator it = ret.begin(); it != ret.end(); ++it) {
it->second.resize(std::distance(it->second.begin(), unique(it->second.begin(), it->second.end())));
}
}
return ret;
}
int main(int argc, char const *argv[]){
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;
}
4 行太长换行输出
//统计单词出现的行数
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <cctype>
#include <iterator>
using std::distance;
#include <algorithm>
using std::unique;
using std::cin; using std::cout;
using std::endl;
using std::map; using std::string;
using std::vector; using std::istream;
//是空白区域为true
bool space(char c){
return isspace(c);
}
//不是空白区域为true
bool not_space(char c){
return !isspace(c);
}
vector<string> split(const string& str){
typedef string::const_iterator iter;
vector<string> ret;
iter i = str.begin();
while(i != str.end()){
//忽略前面的空白
i = find_if(i, str.end(), not_space);
//找到下一个单词的结尾
iter j = find_if(i , str.end(), space);
//复制在[i,j)中的字符
if(i != str.end()){
ret.push_back(string(i, j));
}
i = j;
}
return ret;
}
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;
while(getline(in, line)) {
++line_number;
vector<string> words = find_words(line);
for (vector<string>::const_iterator it = words.begin(); it != words.end(); ++it) {
ret[*it].push_back(line_number);
}
//unique:是把重复的元素移到后面去了,然后返回不重复元素的最后一个的迭代器
for (map<string, vector<int>>::iterator it = ret.begin(); it != ret.end(); ++it) {
it->second.resize(std::distance(it->second.begin(), unique(it->second.begin(), it->second.end())));
}
}
return ret;
}
int main(int argc, char const *argv[]){
map<string, vector<int> > ret = xref(cin);
int linLength = 60;
for (map<string, vector<int> >::const_iterator it = ret.begin(); it != ret.end(); ++it) {
string s = it->first + " occurs on line(s): ";
//换行输出时用,为了对其
string s_spaces(s.size(), ' ');
vector<int>::const_iterator line_it = it->second.begin();
while(line_it != it->second.end()){
//数据出现的行数
string data = std::to_string(*line_it);
//累加数据
if(line_it != it->second.end() - 1){
data += ", ";
}
//超过规定的长度,换行输出
if(s.size() + data.size() > linLength){
cout << s << endl;
s = s_spaces + data;
}else{//没超过规定长度,继续累加
s += data;
}
++line_it;
}
//把没有输出的数据输出
if(s.size() > s_spaces.size()){
cout << s << endl;
}
cout << endl;
}
return 0;
}
5 用链表实现造句程序
//造句
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <cctype>
#include <stdexcept>
#include <cstdlib>
#include <list>
using std::cin; using std::cout;
using std::endl;
using std::map; using std::string;
using std::vector; using std::istream;
using std::logic_error;
using std::domain_error;
using std::list;
typedef vector<string> Rule;
typedef vector<Rule> Rule_collection;
typedef map<string, Rule_collection> Grammar;
//是空白区域为true
bool space(char c){
return isspace(c);
}
//不是空白区域为true
bool not_space(char c){
return !isspace(c);
}
list<string> split(const string& str){
typedef string::const_iterator iter;
list<string> ret;
iter i = str.begin();
while(i != str.end()){
//忽略前面的空白
i = find_if(i, str.end(), not_space);
//找到下一个单词的结尾
iter j = find_if(i , str.end(), space);
//复制在[i,j)中的字符
if(i != str.end()){
ret.push_back(string(i, j));
}
i = j;
}
return ret;
}
Grammar read_grammar(istream& in){
Grammar ret;
string line;
while(getline(in, line)){
//将输入分割成单个单词
list<string> entry = split(line);
if(!entry.empty()){
//用类型来存储相关联的规则
//改变
ret[entry.front()].push_back(Rule(++entry.begin(), entry.end()));
}
}
return ret;
}
bool backeted(const string& s){
return s.size() > 1 && s[0] == '<' && s[s.size() - 1] == '>';
}
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;
}
void gen_aux(const Grammar& g, const string& word, list<string>& ret){
if(!backeted(word)){
ret.push_back(word);
}else{
//为对应的word规则定位
Grammar::const_iterator it = g.find(word);
if(it == g.end()){
throw logic_error("empty rule");
}
//获取可能的规则
const Rule_collection& c = it->second;//进入到vector<vector<string>>
//从规则集合中随机选择一条规则
const Rule& r = c[nrand(c.size())];//到vector<string>
for (Rule::const_iterator i = r.begin(); i != r.end(); ++i) {
gen_aux(g, *i, ret);
}
}
}
list<string> gen_sentence(const Grammar& g){
list<string> ret;
//展开第二个参数传递过来的字符串
//在第一个参数的文法(语句结构)中查找这个字符串并将它的输出放在第三个参数中
gen_aux(g, "<sentence>", ret);
return ret;
}
int main(int argc, char const *argv[]){
list<string> sentence = gen_sentence((read_grammar(cin)));
list<string>::const_iterator it = sentence.begin();
if(!sentence.empty()){
cout << *it;
++it;
}
while(it != sentence.end()){
cout <<" " <<*it;
++it;
}
cout << endl;
return 0;
}
/*
<sentence> the <nm> <v> <p>
<nm> <n>
<nm> <a> <nm>
<n> cat
<n> dog
<a> large
<a> absurd
<v> sits
<v> jumps
<p> on te stairs
<p> under the sky
*/
6 使用栈实现gen_sentence程序
//造句
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <cctype>
#include <stdexcept>
#include <cstdlib>
using std::cin; using std::cout;
using std::endl;
using std::map; using std::string;
using std::vector; using std::istream;
using std::logic_error;
using std::domain_error;
typedef vector<string> Rule;
typedef vector<Rule> Rule_collection;
typedef map<string, Rule_collection> Grammar;
//是空白区域为true
bool space(char c){
return isspace(c);
}
//不是空白区域为true
bool not_space(char c){
return !isspace(c);
}
vector<string> split(const string& str){
typedef string::const_iterator iter;
vector<string> ret;
iter i = str.begin();
while(i != str.end()){
//忽略前面的空白
i = find_if(i, str.end(), not_space);
//找到下一个单词的结尾
iter j = find_if(i , str.end(), space);
//复制在[i,j)中的字符
if(i != str.end()){
ret.push_back(string(i, j));
}
i = j;
}
return ret;
}
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()));
}
}
return ret;
}
bool backeted(const string& s){
return s.size() > 1 && s[0] == '<' && s[s.size() - 1] == '>';
}
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;
}
vector<string> gen_sentence(const Grammar& g){
vector<string> ret;
//展开第二个参数传递过来的字符串
//在第一个参数的文法(语句结构)中查找这个字符串并将它的输出放在第三个参数中
// gen_aux(g, "<sentence>", ret);
vector<string> rules;
rules.push_back("<sentence>");
while(!rules.empty()){
string segment = rules.back();
rules.pop_back();
if(!backeted(segment)){
ret.push_back(segment);
}else{
//为对应的word规则定位
Grammar::const_iterator it = g.find(segment);
if (it == g.end())
throw logic_error("empty rule");
//获取可能的规则
const Rule_collection& c = it->second;//进入到vector<vector<string>>
//从规则集合中随机选择一条规则
const Rule& r = c[nrand(c.size())];//到vector<string>
//到这存储
for (Rule::const_reverse_iterator i = r.rbegin(); i != r.rend(); ++i) {
rules.push_back(*i);
}
}
}
return ret;
}
int main(int argc, char const *argv[]){
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;
}
/*
<sentence> the <nm> <v> <p>
<nm> <n>
<nm> <a> <nm>
<n> cat
<n> dog
<a> large
<a> absurd
<v> sits
<v> jumps
<p> on te stairs
<p> under the sky
*/
7 只有一行的输出line,多行的输出lines
//统计单词出现的行数
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <cctype>
#include <algorithm>
#include <iterator>
using std::cin; using std::cout;
using std::endl;
using std::map; using std::string;
using std::vector; using std::istream;
//是空白区域为true
bool space(char c){
return isspace(c);
}
//不是空白区域为true
bool not_space(char c){
return !isspace(c);
}
vector<string> split(const string& str){
typedef string::const_iterator iter;
vector<string> ret;
iter i = str.begin();
while(i != str.end()){
//忽略前面的空白
i = find_if(i, str.end(), not_space);
//找到下一个单词的结尾
iter j = find_if(i , str.end(), space);
//复制在[i,j)中的字符
if(i != str.end()){
ret.push_back(string(i, j));
}
i = j;
}
return ret;
}
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;
while(getline(in, line)) {
++line_number;
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;
}
int main(int argc, char const *argv[]){
map<string, vector<int> > ret = xref(cin);
map<string, string> ans;
for (map<string, vector<int> >::iterator it = ret.begin(); it != ret.end() ; ++it) {
string count= it->second.size() > 1 ? "lines" : "line";
cout << it->first <<" occurs on line(s): "<< count << endl;
}
return 0;
}
8 查找文件中URL出现的全部行
//找统一资源地址
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cctype>
#include <map>
#include <numeric>
#include <fstream>
#import <iterator>
using std::accumulate;
using std::cin; using std::cout;
using std::endl;
using std::string; using std::vector;
using std::equal; using std::search;
using std::find_if;
using std::map;
using std::multimap;
//没找到字符,返回true
bool not_url_char(char c){
//除数字字母外可能,其他可能出现的URL中的字符
static const string url_ch = "~;!@#$%^&*()_+/'?.=&-:";
//查看c是够出现在一个URl中并返回求反的值
return !(isalnum(c)|| find(url_ch.begin(), url_ch.end(),c) != url_ch.end());
}
string::const_iterator url_end(string::const_iterator b, string::const_iterator e){
return find_if(b, e, not_url_char);
}
string::const_iterator url_beg(string::const_iterator b, string::const_iterator e){
static const string sep = "://";
typedef string::const_iterator iter;
//i标记了查找到的分隔符的位置
iter i = b;
i = search(i ,e , sep.begin(), sep.end());
//如果找到会返回//之前的位置,没有找到会返回输入字符串的末尾之后的那个位置
while(i != e){
//分隔符是否填满整行,://前面有字符串以及://后面至少有一个字符
if(i != b && i + sep.size() != e){
//beg标记协议名称的开头
iter beg = i;
//一直碰到第一个非字母或者字符串开头为止
while(beg != b && isalpha(beg[-1])){
--beg;
}
//是够在分隔符前面以及后面至少有一个字符
if(beg != i && !not_url_char(i[sep.size()])){
return beg;
}
}
//找到的分割符不是URL的一部分
i += sep.size();
}
return e;
}
vector<string> find_urls(const string& s){
vector<string> ret;
typedef string::const_iterator iter;
iter b = s.begin(), e = s.end();
//检查整个输入
while(b != e){
//查找下一个或多个紧跟着://的字母
b = url_beg(b, e);
//查找成功
if(b != e){
//获取url其余部分
iter after = url_end(b, e);
//记住这个url
ret.push_back(string(b,after));
//将b向前推进并查找本行中的其他url
b = after;
}
}
return ret;
}
//分割字符串
vector<string> split(const string& s){
vector<string> ret;
typedef string::size_type string_size;
string_size i = 0;
while(i != s.size()){
//忽略前段的空白:[先前的i,i)中全部字符都是空格
while(i != s.size() && isspace(s[i])){
i++;
}
//找出下一个单词的终结点
string_size j = i;
//[先前的j,j)中的任意字符都不是空格
while(j != s.size() && !isspace(s[j])){
j++;
}
//找到了一些非空白符
if(i != j){
ret.push_back(s.substr(i, j - i));
i = j;
}
}
return ret;
}
int main(int argc, char const *argv[]){
string file = "/Users/macbookpro/CLionProjects/ACM/infile.txt";
std::ifstream infile;
infile.open(file);
string str;
size_t line_number = 1;
map<string, vector<int>> ret;
while(getline(infile, str)){
vector<string> res = split(str);
vector<string> str_url;
for (vector<string>::const_iterator it = res.begin(); it != res.end(); ++it) {
str_url = find_urls(*it);
}
for (vector<string>::const_iterator it = str_url.begin(); it != str_url.end(); ++it) {
ret[*it].push_back(line_number);
}
line_number++;
}
for (map<string, vector<int>>::iterator it = ret.begin(); it != ret.end(); ++it) {
it->second.resize(std::distance(it->second.begin(), std::unique(it->second.begin(), it->second.end())));
}
for (map<string, vector<int>>::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;
}
9 优化nrand函数
#include <iostream>
using std::cin; using std::cout;
using std::endl;
using std::istream;
using std::ostream;
#include <string>
using std::string;
#include <iterator>
using std::inserter;
#include <exception>
using std::domain_error;
int nrand_improved(int n, const int max = RAND_MAX) {
if (n <= 0)
throw domain_error("Argument to nrand is out of range");
if (n <= max)
{
const int bucket_size = max / n;
int r;
do r = rand() / bucket_size;
while (r >= n);
return r;
}
else
{
const int buckets = n / max;
const int remainder_rand = n % max == 0 ? 0 : nrand_improved(n % max);
const int lost = n % max == 0 ? buckets : buckets + 1;
return nrand_improved(max) * buckets + remainder_rand + nrand_improved(lost);
}
}
int main(int argc, char** argv)
{
for (int i = 0; i < 100; i++){
cout << nrand_improved(100, 3) << endl;
}
return 0;
}