Work through exercise 1.3.
This commit is contained in:
@@ -3,5 +3,6 @@ AM_CPPFLAGS += -Wwrite-strings -Wmissing-declarations -Wno-long-long -Werror
|
||||
AM_CPPFLAGS += -Wunused-variable -std=c++14 -D_XOPEN_SOURCE -O0 -g -I.
|
||||
AM_CPPFLAGS += -fno-elide-constructors -Weffc++
|
||||
|
||||
bin_PROGRAMS := ch01ex01
|
||||
ch01ex01_SOURCES := ch01ex01.cc
|
||||
bin_PROGRAMS := ch01ex01 ch01ex03
|
||||
ch01ex01_SOURCES := ch01ex01.cc
|
||||
ch01ex03_SOURCES := ch01ex03.cc
|
||||
203
src/ch01ex01.cc
203
src/ch01ex01.cc
@@ -1,7 +1,10 @@
|
||||
#include <cstdlib>
|
||||
#include <queue>
|
||||
#include <deque>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
@@ -18,18 +21,214 @@ using namespace std;
|
||||
static void
|
||||
problem1(const char *path)
|
||||
{
|
||||
ifstream ifs(path);
|
||||
string line;
|
||||
stack<string> s;
|
||||
|
||||
if (!ifs) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (getline(ifs, line)) {
|
||||
s.push(line);
|
||||
}
|
||||
|
||||
while (!s.empty()) {
|
||||
cout << s.top() << endl;
|
||||
s.pop();
|
||||
}
|
||||
|
||||
ifs.close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Read the first 50 lines of input and then write them out in reverse
|
||||
// order. Read the next 50 lines and then write them out in reverse
|
||||
// order. Do this until there are no more lines left to read, at which
|
||||
// point any remaining lines should be output in reverse order.
|
||||
//
|
||||
// In other words, your output will start with the 50th line, then the
|
||||
// 49th, then the 48th, and so on down to the first line. This will be
|
||||
// followed by the 100th line, followed by the 99th, and so on down to
|
||||
// the 51st line. And so on.
|
||||
//
|
||||
// Your code should never have to store more than 50 lines at any given
|
||||
// time.
|
||||
static void
|
||||
problem2(const char *path)
|
||||
{
|
||||
ifstream ifs(path);
|
||||
string line;
|
||||
stack<string> s;
|
||||
bool stop = false;
|
||||
|
||||
if (!ifs) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (!stop) {
|
||||
while (s.size() < 50) {
|
||||
if (getline(ifs, line)) {
|
||||
s.push(line);
|
||||
} else {
|
||||
stop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (!s.empty()) {
|
||||
cout << s.top() << endl;
|
||||
s.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Read the input one line at a time. At any point after reading the
|
||||
// first 42 lines, if some line is blank (i.e., a string of length 0), then
|
||||
// output the line that occured 42 lines prior to that one. For example,
|
||||
// if Line 242 is blank, then your program should output line 200.
|
||||
// This program should be implemented so that it never stores more
|
||||
// than 43 lines of the input at any given time.
|
||||
static void
|
||||
problem3(const char *path)
|
||||
{
|
||||
ifstream ifs(path);
|
||||
string line;
|
||||
deque<string> q;
|
||||
|
||||
if (!ifs) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (getline(ifs, line)) {
|
||||
if (q.size() > 42) {
|
||||
q.pop_back();
|
||||
}
|
||||
q.push_front(line);
|
||||
|
||||
if (line == "") {
|
||||
cout << q.back() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read the input one line at a time and write each line to the output
|
||||
// if it is not a duplicate of some previous input line. Take special care
|
||||
// so that a file with a lot of duplicate lines does not use more memory
|
||||
// than what is required for the number of unique lines.
|
||||
static void
|
||||
problem4(const char *path)
|
||||
{
|
||||
ifstream ifs(path);
|
||||
string line;
|
||||
set<string> set;
|
||||
|
||||
if (!ifs) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (getline(ifs, line)) {
|
||||
if (set.count(line) == 0) {
|
||||
cout << line << endl;
|
||||
set.insert(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Read the input one line at a time and write each line to the output
|
||||
// only if you have already read this line before. (The end result is that
|
||||
// you remove the first occurrence of each line.) Take special care so
|
||||
// that a file with a lot of duplicate lines does not use more memory
|
||||
// than what is required for the number of unique lines.
|
||||
static void
|
||||
problem5(const char *path)
|
||||
{
|
||||
ifstream ifs(path);
|
||||
string line;
|
||||
set<string> set;
|
||||
|
||||
if (!ifs) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (getline(ifs, line)) {
|
||||
if (set.count(line) == 1) {
|
||||
cout << line << endl;
|
||||
} else {
|
||||
set.insert(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// main should just execute the problems in sequence.
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2) {
|
||||
int problem = -1;
|
||||
|
||||
if (argc < 2) {
|
||||
cerr << "No input file specified, exiting." << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (argc == 3) {
|
||||
problem = stoi(string(argv[2]));
|
||||
}
|
||||
|
||||
if (problem > 0) {
|
||||
switch (problem) {
|
||||
case 1:
|
||||
cout << "*** PROBLEM 1 ***" << endl;
|
||||
problem1(argv[1]);
|
||||
cout << endl << endl;
|
||||
break;
|
||||
case 2:
|
||||
cout << "*** PROBLEM 2 ***" << endl;
|
||||
problem2(argv[1]);
|
||||
cout << endl << endl;
|
||||
break;
|
||||
case 3:
|
||||
cout << "*** PROBLEM 3 ***" << endl;
|
||||
problem3(argv[1]);
|
||||
cout << endl << endl;
|
||||
break;
|
||||
case 4:
|
||||
cout << "*** PROBLEM 4 ***" << endl;
|
||||
problem4(argv[1]);
|
||||
cout << endl << endl;
|
||||
break;
|
||||
case 5:
|
||||
cout << "*** PROBLEM 5 ***" << endl;
|
||||
problem5(argv[1]);
|
||||
cout << endl << endl;
|
||||
break;
|
||||
default:
|
||||
cerr << "Unknown problem " << problem << endl;
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
cout << "*** PROBLEM 1 ***" << endl;
|
||||
problem1(argv[1]);
|
||||
cout << endl << endl;
|
||||
|
||||
cout << "*** PROBLEM 2 ***" << endl;
|
||||
problem2(argv[1]);
|
||||
cout << endl << endl;
|
||||
|
||||
cout << "*** PROBLEM 3 ***" << endl;
|
||||
problem3(argv[1]);
|
||||
cout << endl << endl;
|
||||
|
||||
cout << "*** PROBLEM 4 ***" << endl;
|
||||
problem4(argv[1]);
|
||||
cout << endl << endl;
|
||||
|
||||
cout << "*** PROBLEM 5 ***" << endl;
|
||||
problem5(argv[1]);
|
||||
cout << endl << endl;
|
||||
}
|
||||
67
src/ch01ex03.cc
Normal file
67
src/ch01ex03.cc
Normal file
@@ -0,0 +1,67 @@
|
||||
#include <iostream>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
stack<char> s;
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
string ms(argv[i]);
|
||||
bool matched = true;
|
||||
|
||||
for (auto c : ms) {
|
||||
switch (c) {
|
||||
case '{':
|
||||
case '(':
|
||||
case '[':
|
||||
s.push(c);
|
||||
break;
|
||||
case '}':
|
||||
if (s.top() != '{') {
|
||||
cerr << "Saw '" << s.top() << "' but expected '{'." << endl;
|
||||
matched = false;
|
||||
}
|
||||
else {
|
||||
s.pop();
|
||||
}
|
||||
break;
|
||||
case ']':
|
||||
if (s.top() != '[') {
|
||||
cerr << "Saw '" << s.top() << "' but expected '['." << endl;
|
||||
matched = false;
|
||||
}
|
||||
else {
|
||||
s.pop();
|
||||
}
|
||||
break;
|
||||
case ')':
|
||||
if (s.top() != '(') {
|
||||
cerr << "Saw '" << s.top() << "' but expected '('." << endl;
|
||||
matched = false;
|
||||
}
|
||||
else {
|
||||
s.pop();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cerr << "Invalid character in string: " << c << endl;
|
||||
matched = false;
|
||||
}
|
||||
|
||||
if (!matched) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!matched) {
|
||||
cerr << "'" << ms << "' is not a matched string." << endl;
|
||||
}
|
||||
else {
|
||||
cout << "'" << ms << "' is a matched string." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user