(Ebook) Essential Algorithms: A Practical Approach To Computer Algorithms by Rod Stephens ISBN 9781118612101, 1118612108
(Ebook) Essential Algorithms: A Practical Approach To Computer Algorithms by Rod Stephens ISBN 9781118612101, 1118612108
https://ebooknice.com/product/essential-algorithms-31030430
https://ebooknice.com/product/essential-algorithms-a-practical-
approach-to-computer-algorithms-using-python-and-c-12274474
https://ebooknice.com/product/essential-algorithms-a-practical-
approach-to-computer-algorithms-using-python-and-c-second-
edition-57280052
(Ebook) Pro Machine Learning Algorithms: A Hands-On Approach to
Implementing Algorithms in Python and R by V Kishore Ayyadevara
https://ebooknice.com/product/pro-machine-learning-algorithms-a-hands-
on-approach-to-implementing-algorithms-in-python-and-r-50195058
https://ebooknice.com/product/algorithms-sequential-parallel-a-
unified-approach-electrical-and-computer-engineering-series-2539134
https://ebooknice.com/product/algebraic-graph-algorithms-a-practical-
guide-using-python-undergraduate-topics-in-computer-science-36373836
https://ebooknice.com/product/optimization-of-computer-networks-
modeling-and-algorithms-a-hands-on-approach-5536552
https://ebooknice.com/product/practical-algorithms-for-3d-computer-
graphics-second-edition-5145374
Table of Contents
Chapter 1: Algorithm Basics
Approach
Algorithms and Data Structures
Pseudocode
Algorithm Features
Practical Considerations
Summary
Exercises
Chapter 2: Numerical Algorithms
Randomizing Data
Finding Greatest Common Divisors
Performing Exponentiation
Working with Prime Numbers
Performing Numerical Integration
Finding Zeros
Summary
Exercises
Chapter 3: Linked Lists
Basic Concepts
Singly Linked Lists
Doubly Linked Lists
Sorted Linked Lists
Linked-List Algorithms
2
Linked List Selectionsort
Multithreaded Linked Lists
Linked Lists with Loops
Summary
Exercises
Chapter 4: Arrays
Basic Concepts
One-dimensional Arrays
Nonzero Lower Bounds
Triangular Arrays
Sparse Arrays
Matrices
Summary
Exercises
Chapter 5: Stacks and Queues
Stacks
Queues
Summary
Exercises
Chapter 6: Sorting
O(N2) Algorithms
O(N log N) Algorithms
Sub O(N log N) Algorithms
Summary
3
Exercises
Chapter 7: Searching
Linear Search
Binary Search
Interpolation Search
Summary
Exercises
Chapter 8: Hash Tables
Hash Table Fundamentals
Chaining
Open Addressing
Summary
Exercises
Chapter 9: Recursion
Basic Algorithms
Graphical Algorithms
Backtracking Algorithms
Selections and Permutations
Recursion Removal
Summary
Exercises
Chapter 10: Trees
Tree Terminology
Binary Tree Properties
4
Tree Representations
Tree Traversal
Sorted Trees
Threaded Trees
Specialized Tree Algorithms
Summary
Exercises
Chapter 11: Balanced Trees
AVL Trees
2-3 Trees
B-Trees
Balanced Tree Variations
Summary
Exercises
Chapter 12: Decision Trees
Searching Game Trees
Searching General Decision Trees
Summary
Exercises
Chapter 13: Basic Network Algorithms
Network Terminology
Network Representations
Traversals
Finding Paths
5
Summary
Exercises
Chapter 14: More Network Algorithms
Topological Sorting
Cycle Detection
Map Coloring
Maximal Flow
Summary
Exercises
Chapter 15: String Algorithms
Matching Parentheses
Pattern Matching
String Searching
Calculating Edit Distance
Summary
Exercises
Chapter 16: Cryptography
Terminology
Transposition Ciphers
Substitution Ciphers
Block Ciphers
Public-Key Encryption and RSA
Other Uses for Cryptography
Summary
6
Exercises
Chapter 17: Complexity Theory
Notation
Complexity Classes
Reductions
NP-Hardness
Detection, Reporting, and Optimization Problems
NP-Complete Problems
Summary
Exercises
Chapter 18: Distributed Algorithms
Types of Parallelism
Distributed Algorithms
Summary
Exercises
Chapter 19: Interview Puzzles
Asking Interview Puzzle Questions
Answering Interview Puzzle Questions
Summary
Exercises
Appendix A: Summary of Algorithmic Concepts
Chapter 1: Algorithm Basics
Chapter 2: Numeric Algorithms
Chapter 3: Linked Lists
7
Chapter 4: Arrays
Chapter 5: Stacks and Queues
Chapter 6: Sorting
Chapter 7: Searching
Chapter 8: Hash Tables
Chapter 9: Recursion
Chapter 10: Trees
Chapter 11: Balanced Trees
Chapter 12: Decision Trees
Chapter 13: Basic Network Algorithms
Chapter 14: More Network Algorithms
Chapter 15: String Algorithms
Chapter 16: Cryptography
Chapter 17: Complexity Theory
Chapter 18: Distributed Algorithms
Chapter 19: Interview Puzzles
Appendix B: Solutions to Exercises
Chapter 1: Algorithm Basics
Chapter 2: Numerical Algorithms
Chapter 3: Linked Lists
Chapter 4: Arrays
Chapter 5: Stacks and Queues
Chapter 6: Sorting
Chapter 7: Searching
8
Chapter 8: Hash Tables
Chapter 9: Recursion
Chapter 10: Trees
Chapter 11: Balanced Trees
Chapter 12: Decision Trees
Chapter 13: Basic Network Algorithms
Chapter 14: More Network Algorithms
Chapter 15: String Algorithms
Chapter 16: Encryption
Chapter 17: Complexity Theory
Chapter 18: Distributed Algorithms
Chapter 19: Interview Puzzles
Glossary
Introduction
9
Chapter 1
Algorithm Basics
Before you jump into the study of algorithms, you need a little
background. To begin with, you need to know that, simply stated, an
algorithm is a recipe for getting something done. It defines the steps for
performing a task in a certain way.
That definition seems simple enough, but no one writes algorithms for
performing extremely simple tasks. No one writes instructions for how to
access the fourth element in an array. It is just assumed that this is part of
the definition of an array and that you know how to do it (if you know
how to use the programming language in question).
Normally people write algorithms only for difficult tasks. Algorithms
explain how to find the solution to a complicated algebra problem, how to
find the shortest path through a network containing thousands of streets, or
how to find the best mix of hundreds of investments to optimize profits.
This chapter explains some of the basic algorithmic concepts you should
understand if you want to get the most out of your study of algorithms.
It may be tempting to skip this chapter and jump to studying specific
algorithms, but you should at least skim this material. Pay close attention
to the section “Big O Notation,” because a good understanding of runtime
performance can mean the difference between an algorithm performing its
task in seconds, hours, or not at all.
Approach
To get the most out of an algorithm, you must be able to do more than
simply follow its steps. You need to understand the following:
• The algorithm's behavior. Does it find the best possible solution,
or does it just find a good solution? Could there be multiple best
solutions? Is there a reason to pick one “best” solution over the
others?
10
• The algorithm's speed. Is it fast? Slow? Is it usually fast but
sometimes slow for certain inputs?
• The algorithm's memory requirements. How much memory will
the algorithm need? Is this a reasonable amount? Does the
algorithm require billions of terabytes more memory than a
computer could possibly have (at least today)?
• The main techniques the algorithm uses. Can you reuse those
techniques to solve similar problems?
This book covers all these topics. It does not, however, attempt to cover
every detail of every algorithm with mathematical precision. It uses an
intuitive approach to explain algorithms and their performance, but it does
not analyze performance in rigorous detail. Although that kind of proof
can be interesting, it can also be confusing and take up a lot of space,
providing a level of detail that is unnecessary for most programmers. This
book, after all, is intended primarily for programming professionals who
need to get a job done.
This book's chapters group algorithms that have related themes.
Sometimes the theme is the task they perform (sorting, searching, network
algorithms), sometimes it's the data structures they use (linked lists,
arrays, hash tables, trees), and sometimes it's the techniques they use
(recursion, decision trees, distributed algorithms). At a high level, these
groupings may seem arbitrary, but when you read about the algorithms,
you'll see that they fit together.
In addition to those categories, many algorithms have underlying themes
that cross chapter boundaries. For example, tree algorithms (Chapters 10,
11, and 12) tend to be highly recursive (Chapter 9). Linked lists (Chapter
3) can be used to build arrays (Chapter 4), hash tables (Chapter 8), stacks
(Chapter 5), and queues (Chapter 5). The ideas of references and pointers
are used to build linked lists (Chapter 3), trees (Chapters 10, 11, and 12),
and networks (Chapters 13 and 14). As you read, watch for these common
threads. Appendix A summarizes common strategies programs use to
make these ideas easier to follow.
11
Algorithms and Data
Structures
An algorithm is a recipe for performing a certain task. A data structure is
a way of arranging data to make solving a particular problem easier. A
data structure could be a way of arranging values in an array, a linked list
that connects items in a certain pattern, a tree, a graph, a network, or
something even more exotic.
Often algorithms are closely tied to data structures. For example, the edit
distance algorithm described in Chapter 15 uses a network to determine
how similar two strings are. The algorithm is tied closely to the network
and won't work without it.
Often an algorithm says, “Build a certain data structure and then use it in a
certain way.” The algorithm can't exist without the data structure, and
there's no point in building the data structure if you don't plan to use it
with the algorithm.
Pseudocode
To make the algorithms described in this book as useful as possible, they
are first described in intuitive English terms. From this high-level
explanation, you should be able to implement the algorithm in most
programming languages.
Often, however, an algorithm's implementation contains niggling little
details that can make implementation hard. To make handling those
details easier, the algorithms are also described in pseudocode.
Pseudocode is text that is a lot like a programming language but that is not
really a programming language. The idea is to give you the structure and
details you would need to implement the algorithm in code without tying
the algorithm to a particular programming language. Hopefully you can
translate the pseudocode into actual code to run on your computer.
12
The following snippet shows an example of pseudocode for an algorithm
that calculates the greatest common divisor (GCD) of two integers:
// Find the greatest common divisor of a and b.
// GCD(a, b) = GCD(b, a Mod b).
Integer: Gcd(Integer: a, Integer: b)
While (b != 0)
// Calculate the remainder.
Integer: remainder = a Mod b
// Calculate GCD(b, remainder).
a = b
b = remainder
End While
// GCD(a, 0) is a.
Return a
End Gcd
The first actual line of code is the algorithm's declaration. This algorithm
is called Gcd and returns an integer result. It takes two parameters named
a and b, both of which are integers.
Note
Chunks of code that perform a task, optionally returning a result, are variously called
routines, subroutines, methods, procedures, subprocedures, or functions.
The code after the declaration is indented to show that it is part of the
method. The first line in the method's body begins a While loop. The
code indented below the While statement is executed as long as the
condition in the While statement remains true.
The While loop ends with an End While statement. This statement
isn't strictly necessary, because the indentation shows where the loop ends,
but it provides a reminder of what kind of block of statements is ending.
13
The method exits at the Return statement. This algorithm returns a
value, so this Return statement indicates which value the algorithm
should return. If the algorithm doesn't return any value, such as if its
purpose is to arrange values or build a data structure, the Return
statement isn't followed by a return value.
The code in this example is fairly close to actual programming code.
Other examples may contain instructions or values described in English.
In those cases, the instructions are enclosed in angle brackets (<>) to
indicate that you need to translate the English instructions into program
code.
Normally when a parameter or variable is declared (in the Gcd algorithm,
this includes the parameters a and b and the variable remainder), its
data type is given before it, followed by a colon, as in Integer:
remainder. The data type may be omitted for simple integer looping
variables, as in For i = 1 To 10.
14
One basic data structure that may be unfamiliar to you depending on
which programming languages you know is a List. A List is similar
to a self-expanding array. It provides an Add method that lets you add an
item to the end of the list. For example, the following pseudocode creates
a List Of Integer that contains the numbers 1 through 10:
List Of Integer: numbers
For i = 1 To 10
numbers.Add(i)
Next i
15
the book's discussion forum at www.wiley.com/go/
essentialalgorithms or e-mail me at
[email protected]. I'll point you in the right
direction.
One problem with pseudocode is that it has no compiler to detect errors.
As a check of the basic algorithm, and to give you some actual code to use
for a reference, C# implementations of most of the algorithms and many
of the exercises are available for download on the book's website.
Algorithm Features
A good algorithm must have three features: correctness, maintainability,
and efficiency.
Obviously if an algorithm doesn't solve the problem for which it was
designed, it's not much use. If it doesn't produce correct answers, there's
little point in using it.
Note
Interestingly, some algorithms produce correct answers only some of the time but are still
useful. For example, an algorithm may be able to give you some information with a
certain probability. In that case you may be able to rerun the algorithm many times to
increase your confidence that the answer is correct. Fermat's primality test, described in
Chapter 2, is this kind of algorithm.
Note
This doesn't mean it isn't worth studying confusing and difficult algorithms. Even if you
have trouble implementing an algorithm, you may learn a lot in the attempt. Over time
your algorithmic intuition and skill will increase, so algorithms you once thought were
confusing will seem easier to handle. You must always test all algorithms thoroughly,
however, to make sure they are producing correct results.
16
Most developers spend a lot of effort on efficiency, and efficiency is
certainly important. If an algorithm produces a correct result and is simple
to implement and debug, it's still not much use if it takes seven years to
finish or if it requires more memory than a computer can possibly hold.
In order to study an algorithm's performance, computer scientists ask how
its performance changes as the size of the problem changes. If you double
the number of values the algorithm is processing, does the runtime
double? Does it increase by a factor of 4? Does it increase exponentially
so that it suddenly takes years to finish?
You can ask the same questions about memory usage or any other
resource that the algorithm requires. If you double the size of the problem,
does the amount of memory required double?
You can also ask the same questions with respect to the algorithm's
performance under different circumstances. What is the algorithm's
worst-case performance? How likely is the worst case to occur? If you run
the algorithm on a large set of random data, what is its average-case
performance?
To get a feeling for how problem size relates to performance, computer
scientists use Big O notation, described in the following section.
Big O Notation
Big O notation uses a function to describe how the algorithm's worst-case
performance relates to the problem size as the size grows very large. (This
is sometimes called the program's asymptotic performance.) The function
is written within parentheses after a capital letter O.
Note
17
Often O(N2) is pronounced “order N squared.” For example, you might say, “The
quicksort algorithm described in Chapter 6 has a worst-case performance of order N
squared.”
There are five basic rules for calculating an algorithm's Big O notation:
1. If an algorithm performs a certain sequence of steps f(N) times
for a mathematical function f, it takes O(f(N)) steps.
2. If an algorithm performs an operation that takes O(f(N)) steps
and then performs a second operation that takes O(g(N)) steps for
functions f and g, the algorithm's total performance is O(f(N) +
g(N)).
3. If an algorithm takes O(f(N) + g(N)) and the function f(N) is
greater than g(N) for large N, the algorithm's performance can be
simplified to O(f(N)).
4. If an algorithm performs an operation that takes O(f(N)) steps,
and for every step in that operation it performs another O(g(N))
steps, the algorithm's total performance is O(f(N) × g(N)).
5. Ignore constant multiples. If C is a constant, O(C × f(N)) is the
same as O(f(N)), and O(f(C × N)) is the same as O(f(N)).
These rules may seem a bit formal, with all the f(N) and g(N), but they're
fairly easy to apply. If they seem confusing, a few examples should make
them easier to understand.
Rule 1
If an algorithm performs a certain sequence of steps f(N) times for a
mathematical function f, it takes O(f(N)) steps.
Consider the following algorithm, written in pseudocode, for finding the
largest integer in an array:
Integer: FindLargest(Integer: array[])
Integer: largest = array[0]
For i = 1 To <largest index>
If (array[i] > largest) Then largest =
array[i]
Next i
Return largest
End FindLargest
18
The FindLargest algorithm takes as a parameter an array of integers
and returns an integer result. It starts by setting the variable largest
equal to the first value in the array.
It then loops through the remaining values in the array, comparing each to
largest. If it finds a value that is larger than largest, the program
sets largest equal to that value.
This algorithm examines each of the N items in the array once, so it has
O(N) performance.
Note
Often algorithms spend most of their time in loops. There's no way an algorithm can
execute more than N steps with a fixed number of code lines unless it contains some sort
of loop.
Study an algorithm's loops to figure out how much time it takes.
Rule 2
If an algorithm performs an operation that takes O(f(N)) steps and then
performs a second operation that takes O(g(N)) steps for functions f and
g, the algorithm's total performance is O(f(N) + g(N)).
If you look again at the FindLargest algorithm shown in the
preceding section, you'll see that a few steps are not actually inside the
loop. The following pseudocode shows the same steps, with their runtime
order shown to the right in comments:
Integer: FindLargest(Integer: array[])
Integer: largest =
array[0] // O(1)
For i = 1 To <largest
index> // O(N)
If (array[i] > largest) Then largest =
array[i]
Next i
Return
largest //
O(1)
End FindLargest
19
This algorithm performs one setup step before it enters its loop and then
performs one more step after it finishes the loop. Both of those steps have
performance O(1) (they're each just a single step), so the total runtime for
the algorithm is really O(1 + N + 1). You can use normal algebra to
combine terms to rewrite this as O(2 + N).
Rule 3
If an algorithm takes O(f(N) + g(N)) and the function f(N) is greater than
g(N) for large N, the algorithm's performance can be simplified to
O(f(N)).
The preceding example showed that the FindLargest algorithm has
runtime O(2 + N). When N grows large, the function N is larger than the
constant value 2, so O(2 + N) simplifies to O(N).
Ignoring the smaller function lets you focus on the algorithm's asymptotic
behavior as the problem size becomes very large. It also lets you ignore
relatively small setup and cleanup tasks. If an algorithm spends some time
building simple data structures and otherwise getting ready to perform a
big computation, you can ignore the setup time as long as it's small
compared to the length of the main calculation.
Rule 4
If an algorithm performs an operation that takes O(f(N)) steps, and for
every step in that operation it performs another O(g(N)) steps, the
algorithm's total performance is O(f(N) + g(N)).
Consider the following algorithm that determines whether an array
contains any duplicate items. (Note that this isn't the most efficient way to
detect duplicates.)
Boolean: ContainsDuplicates(Integer: array[])
// Loop over all of the array's items.
For i = 0 To <largest index>
For j = 0 To <largest index>
// See if these two items are duplicates.
If (i != j) Then
If (array[i] == array[j]) Then
Return True
20
Random documents with unrelated
content Scribd suggests to you:
chapters[732]. The most important additions are to Ohthere and
Wulfstan.
be found in the geographical introduction which
Orosius prefixes to his work. It is here that Alfred inserts the well-
known description of the geography of Germany, which for him
includes all central Europe from the Rhine on the west to the Don on
the east, and from the Danube on the south to the White Sea on the
north[733]. Here too are inserted the yet more famous accounts of
the voyages of Ohthere[734] and Wulfstan[735], on which so much
has been written. Ohthere’s account begins: ‘Ohthere told his lord
king Alfred that of all the Northmen he dwelt furthest to the North’;
and this is the only direct evidence which the work contains as to its
authorship. These accounts and also the description of Germany,
which, like them, must have been carefully derived from oral
information, illustrate what Asser tells of Alfred’s intercourse with
strangers and his eagerness to learn from them[736], a trait which
was characteristic also of the great Charles[737]. In the historical part
the chief additions are the description of a Roman triumph[738], and
of the temple of Janus[739]. But there are endless smaller additions;
and of these one of the most interesting is the anecdote, ultimately
derived from Suetonius, how Titus used to say that the day was a
lost day on which he had done no good to any one[740]. This saying
is quoted also in the Chronicle, and is one of the links connecting the
two works[741]. We can understand how this saying of the ‘deliciae
generis humani’ would come home to the heart of England’s
darling[742]. Some of these shorter insertions are brief explanatory
notes[743] like those which we have already met with in the Cura
Pastoralis, and, like them, are by no means always correct.
§ 101. Sometimes the explanations are longer;
and many of these are due entirely to Alfred’s Editorial
explanations.
imagination, and are intended to make clear to us
how, in his view, the event narrated came about. It is not in
accordance with our modern notions that editorial explanations of
this kind should be incorporated in the text of an author. But the
idea of literary property is a comparatively modern one, and
footnotes and appendices had not then been invented. It is more
questionable when the phrase ‘cwæð Orosius’ which Alfred
frequently[744] uses to indicate that a sentiment or a statement is
his author’s, not his own, is used, as is the case in one or two
instances, to introduce something for which there is no warrant in
the original; for instance, one of the passages about fate alluded to
above[745].
Of these editorial explanations the most
interesting perhaps are those which relate to These frequently
relate to military
military matters; because they seem in some cases matters.
to reflect Alfred’s own military experience—a point
which Schilling has not noticed. For instance, when Alfred gives as
Hannibal’s reason for his terrible winter march over the Apennines,
that ‘he knew that Flaminius the consul was fancying that he might
remain securely in his winter quarters, … being fully persuaded that
no one would attempt such a march by reason of the intense
cold[746],’ we think of the sudden swoop of the Danes on Alfred at
Chippenham that Epiphany tide 878[747]; the stratagem of a
simulated flight, by which he explains the defeat of Regulus[748], is
one which there is reason to believe that the Danes more than once
resorted to[749]; as also the device which he attributes to Hannibal,
without any warrant from the original text, of sending out parties to
ravage in various directions in order to make the enemy imagine that
his whole force was occupied in this manner[750]; though this also
closely resembles the feigned attacks which Alfred himself made
from Athelney, in order to mask his advance in force to
Ethandun[751].
§ 102. The same is true of some things for which
there is a basis in Orosius himself; for instance, the Passages in
Orosius illustrated
story how, within sixty days from the felling of the by Alfred’s own
trees, Duilius had a fleet of 130 ships ready ‘both experience.
with mast and sail[752]’ recalls Alfred’s own
shipbuilding efforts; the story how Dercyllidas dealt Anecdote of
Nelson.
with the opposing forces of Pharnabazus and
Tissaphernes is extraordinarily like Alfred’s attempt to detach the
Danes of Milton from those at Appledore in 893 [894][753]: ‘As soon
as the Lacedemonian general knew that he had to deal with two
hosts (heras), he thought it more advisable to make peace with the
one, in order that he might the more easily overcome the
other[754]’; while I have already suggested that the twofold division
of the Amazonian host[755], one to remain at home while the other
was on active service, may have even suggested Alfred’s similar
division of the native fyrd or militia. And, indeed, if the workings of
the human mind were always traceable, I fancy we should find,
more often than is commonly supposed, that what seem like brilliant
intuitions on the part of great commanders and statesmen, had
really been suggested by their reading. Nor is this any detraction
from their originality. To remember at the right time, and apply in
the right way, the hints furnished by previous experience, is as much
a mark of genius as invention. There is an interesting tradition that
Nelson’s manœuvre of anchoring his vessels by the stern at the
bombardment of Copenhagen in 1801, was suggested by the fact
that he had that morning been reading the twenty-seventh chapter
of the Acts, which tells how St. Paul’s shipwrecked companions ‘cast
four anchors out of the stern, and wished for the day[756].’
§ 103. Often the additions and expansions let us
see Alfred’s own sentiments; his religious The alterations
sometimes
feelings[757], his admiration for genius, patriotism, illustrate Alfred’s
and courage, as exemplified in such men as own sentiments.
Mistakes. Alfred’s
Alexander[758], Scaevola[759], Regulus[760], the character
two Scipios[761] and Caesar[762]; his disgust at displayed.
ingratitude to God[763] and man[764], at
cruelty[765], treachery[766], or sloth[767]. The omissions are often
dictated by similar motives. He leaves out or abridges many of the
civil wars, the calamities, the crimes, the unclean mythologies[768],
over which Orosius gloated as proofs of heathen depravity; though
often the omissions have no special motive beyond the necessity for
shortening the work. It must be confessed that these omissions
frequently have the effect of wholly dislocating the succession of
events. And it may be said generally that Alfred, though he
apprehends individual incidents with extraordinary vividness, is by no
means clear as to the connexion of events. For the latter quality
greater knowledge was required than was accessible in his day. In
regard to the additions, moreover, we must bear in mind the
possibility that some of them may be due, not to Alfred himself, but
to interpolations or glosses in the MSS. which he used. This, as we
shall see[769], is a consideration of great importance in the case of
the Boethius, but it has been proved to apply to one or two
passages of the Orosius also[770]. That there are many errors as to
persons bearing the same or similar names[771], many confusions of
personal and geographical appellations[772], many quaint mistakes
of translation[773] and of fact, as when he says that Augustus took
his name from the eighth month of the year instead of vice
versa[774], turns the snake-charming tribe of Psylli[775] into a kind of
serpent, and infers from Augustus’ heart-broken exclamation, ‘Vare,
redde legiones,’ that that ill-fated commander had escaped alive
from his defeat[776]; this is only what we might expect, and it would
be ungracious to dwell upon such things[777]. Dr. Schilling has truly
and excellently said[778] of the Orosius: ‘We see Alfred here weak in
historical and linguistic knowledge; but we see him also simple,
high-hearted, and earnest; full of warm appreciation for all that is
good, and of scorn for all that is evil; putting himself to school that
he may educate and raise his people.’
LECTURE VI
LITERARY WORKS (continued); SUMMARY
AND CONCLUSION
The same MS. contains, between Bede’s Preface and the History
proper, a copy of the West Saxon genealogy in the exact form in
which it appears in MS. of the Saxon Chronicle; i.e. it comes
down to the accession of Alfred, and no further. This again connects
the work with Alfred. The Cambridge MS. is, as far as we can test it,
an undoubted copy of one which exists in the library of my own
college. This is unfortunately imperfect, both at the beginning and
the end. But if, as is likely, it also contained originally the distich and
the pedigree, the evidence is thrown yet further back[787].
Curiously enough both Laȝamon[788] and Rudborne[789] speak of
the Saxon version as if it were Bede’s own.
§ 105. The question of its authorship must not
be regarded as outside the pale of discussion. Only The negative
arguments
I do not think that the arguments hitherto inconclusive. The
advanced are sufficient to establish a negative argument from
dialect.
conclusion. As to Dr. Miller’s Mercian theory, I may
say at once that I have no pretensions to pose as an expert in early
English dialects. I can get up no enthusiasm for the minute
distinctions of form and spelling which form their criteria. They have
for me only the practical and unpleasant interest that they oblige me
often to look up a word in three or four different places in the
dictionary before finding it. I may however mention that Professor
Schipper, the latest editor of the Anglo-Saxon Bede[790], does not
regard the Mercian theory as established[791]. But even if it were
established, it does not seem to me incompatible with Alfred’s
authorship. It is agreed that all our existing MSS. go back to a single
archetype, though they branch off into two groups which form to
some extent a twofold recension[792]. The scribe of that archetypal
MS. may have been a Mercian, and there may have been other MSS.
in which these Mercian peculiarities were wanting. Even if it be
assumed (for it certainly could not be proved), that this Mercian
archetype was the original MS. of all, it is equally open to us to
suppose that the scribe to whom Alfred dictated his translation in the
first instance may have been a Mercian. Or again it is quite possible
that the Mercian characteristics, if they exist, may be due to the
influence of the Mercian scholars who assisted Alfred in his work—
Plegmund, Werferth, and the two Mercian chaplains mentioned by
Asser[793]. And it is some confirmation of this that there is a certain
affinity noticeable between the diction and style of the Bede
translation and that of the earlier or unrevised version of the
Dialogues, which, as we have seen, there is good reason to attribute
to Werferth[794].
§ 106. As to the over-literalness of the
translation in places, the fact must be admitted, Argument from
style. Influence of
though the extent of it has been, I think, Latin on early
somewhat exaggerated. The cases fall under three prose. The Bede
heads: (1) where a Latin construction is may never have
been finally
unidiomatically imitated in the Saxon[795]; this revised.
applies especially to constructions with the ablative absolute[796],
the accusative and infinitive[797], and the use of the passive
voice[798], the range of which is much more restricted in Saxon than
in Latin[799]; (2) where a Latin word is translated by a Saxon one
which may correspond fairly well with the general meaning of the
Latin word, but does not give its sense in the particular
passage[800]; (3) where a phrase or sentence is translated, to use
Alfred’s own expression, ‘word by word,’ instead of ‘sense by
sense[801].’ To all these classes the explanation suggested by
Professor Schipper would often apply, viz. that the translator may
have embodied in his work interlinear glosses which had been made
to assist him; and he cites in illustration the difference between the
West Saxon and Northumbrian versions of the Gospels, the former of
which is a genuine translation, while the latter is an interlinear gloss
made word for word[802]. Some however of the cases where Latin
constructions are reproduced, and also one or two of the second
class, give me the impression, not that the translator could not have
translated more idiomatically if he had pleased, but rather that he
was trying experiments with the language. The development of early
prose in almost all European languages has been largely influenced
by Latin models, and it was only experience which could show how
far the process of assimilation might be carried. Similarly for some
two centuries after the Renaissance English prose literature is full of
experimentally transplanted Latinisms, of which a large proportion
failed to make good their footing in the language. Another possibility
must also be borne in mind; that the Bede may never have received
Alfred’s final revision. We have seen that in the case of the Dialogues
an extensive revision was found desirable at a later time, and we
seem to have traces of a partial revision of the Bede in the younger
group of MSS. mentioned above, in which not only does the
translation vary, at times very considerably[803], but a passage is
inserted which the earlier recension omits[804], and conversely[805].
When this partial revision was made I cannot say, but probably not
by Alfred himself. On the whole, then, I do not regard Mr. Sweet’s or
Dr. Miller’s argument as conclusive, either against Alfred’s authorship
of the Bede translation, or against the priority of the Orosius.
§ 107. I have already said[806] that the principal
changes made by Alfred in the Bede are in the way Omissions made
by Alfred in the
of omission, the additions being comparatively Bede. The Easter
slight. It is worth while to see what considerations Controversy.
guided him in this. First of all he omits almost all
documents[807], in two instances he just gives a brief summary of a
letter in oratio obliqua[808]. He seems at first to have intended to
omit the interrogations and responses of Augustine and Gregory, but
afterwards to have changed his mind, as in all the MSS. they occur
after the third book instead of in their proper place near the end of
the first[809]. He also omits all the metrical compositions, epitaphs,
&c.[810], which occur in the course of the work. Then, too, he omits
almost everything bearing on the Easter Controversy[811]; partly no
doubt because he felt, as modern readers feel, the intolerable
tediousness of the whole thing; but partly also, we may well believe,
because he disliked the bitterness which even the gentle Bede shows
on this question[812], for there are little touches which seem to
prove that the piety and self-devotion of the Celtic missionaries had
made a deep impression on his heart[813]. The early history prior to
the conversion of the Saxons is also a good deal abbreviated[814], no
doubt as having less direct interest for his readers. So the
description of the sacred places which Bede largely borrowed from
Arculfus is omitted, probably for similar reasons[815].
§ 108. It has often formed a subject both of
wonder and regret that Alfred should not have The additions
unimportant.
enriched the Bede with additions drawn from his
own knowledge of the traditions of his people, as he might so easily
have done. Reverence for his original may have had something to do
with this; but I agree with Professor Wülker[816] that the main
reason probably was, because all that Alfred desired in this line had
already been done in the compilation of the Saxon Chronicle. It is
confirmatory of this that the chronological summary appended to his
history by Bede, which had, as I have elsewhere shown[817], such
an important influence on the development of annalistic writing in
general, and of the Saxon Chronicle in particular, is omitted in the
Bede translation.
Smaller additions and expansions there are, but they seldom really
add anything to the narrative. They are as a rule merely inserted to
make it a little more clear[818], or a little more vivid, or a little more
in accordance with the translator’s ideas[819]. Occasionally, though
rarely, they show a touch of personal feeling; as where Diocletian is
characterised as the bad emperor[820], Constantine as the good
emperor[821], and Aidan as the good bishop[822]. Sometimes, as in
the other works, they are brief explanations of things which the
readers might not know[823]. Occasionally statements of Bede’s are
altered[824], or omitted[825], because they were no longer
applicable, or they are marked distinctly as being Bede’s and not
Alfred’s[826]. But in other cases similar statements are retained,
though it would not be safe to argue from this that the state of
things indicated still subsisted in Alfred’s day[827].
Here too there are mistakes[828], though fewer
Mistakes.
and less serious than in the Orosius. In some cases
they may be due to erroneous readings in the MS. which Alfred
used[829]. In one or two instances Alfred’s version shows a
remarkable divergence of historical fact, which can hardly arise
wholly from misunderstanding[830].
But on the whole the translation is a worthy one,
preserving, and in one or two instances Merits of the
translation.
enhancing[831], the beauty of the original, the most
beautiful historical work which the Church had produced since Luke
and John wrote their Gospels.
One incidental merit of the translation, as Stubbs has
remarked[832], is that it enables us to equate the Saxon technical
terms of officers and institutions with the corresponding Latin
ones[833].
§ 109. We come now to what is in many respects
the most interesting and important of all Alfred’s The translation of
Boethius. Fame of
literary works, viz. the translation of Boethius on the original in the
the Consolation of Philosophy. It is here that the Middle Ages.
additions made by Alfred to his original give us the Causes of this
popularity; its
clearest insight into his own character and modes form. Sympathy
of thought. And the original is in itself one of the with the author.
most noteworthy books of the Middle Ages. Just as
Orosius was to those ages the accepted manual of universal
history[834], and the Cura Pastoralis their accepted manual of
Spiritual Counsel, so the Consolatio of Boethius was their accepted
manual of practical and speculative philosophy; the one channel
through which some tincture of ancient speculation passed into the
popular thought of the early Middle Ages. Perhaps no book except
the Bible and the Imitatio has been translated into so many
languages; and in more than one European country the early
translations of the Consolatio have had an important influence on
the development of a vernacular literature[835]. For this popularity
several reasons may be given. Something was probably due to the
form of the work, which is written in that mixture of verse and prose
known as the Satura Menippaea[836]. The lyrics of the Consolatio
won the enthusiastic admiration of the great Renaissance scholar, F.
C. Scaliger[837], and I must confess that to me they seem extremely
beautiful, though their beauty is of a somewhat frosty order. But if
they have something of the hardness and coldness of marble, they
have also its purity and high polish[838]. But the chief reason was,
no doubt, sympathy with the author’s misfortunes, whose sudden
fall, from being the favourite and chief minister of Theodoric, to
prison and to death, made him one of the most signal examples in
that ever-lengthening treatise De casibus illustrium uirorum, on
which the Middle Ages pondered with intense and morbid interest,
feeding that contempt for the world[839] and all things human, which
finds such passionate expression in many mediaeval writings:—
The translation exists in only two MSS., one in the arguments for the
Cottonian Collection[890], the other in the most part purely
subjective.
Bodleian [891] . In the older or Cottonian MS. the
metrical parts of Boethius are, with three exceptions[892], rendered
into alliterative Saxon verse; in the later or Bodleian MS. they are
rendered into prose. It is as to Alfred’s authorship of the alliterative
poems that the controversy has raged; and those who deny their
authenticity are compelled to deny also the authenticity of the two
proems in prose and verse[893], in both of which the poems are
distinctly ascribed to Alfred. The question, though interesting as a
literary problem, is not intrinsically of great importance. The poems
are not of the highest order, though they have been, I think, unduly
depreciated. Alfred’s fame will not be much exalted if he wrote them,
or much depressed if they should be adjudged to another. I must
confess, however, that a great deal of the argument on the negative
side seems to me to be of that purely arbitrary and subjective kind
which in its ultimate analysis amounts to this: ‘it can’t have been so,
because I don’t think that it was[894].’
§ 113. One thing is agreed on all sides; the verse translation is
made from the prose translation, and is not an independent
rendering made direct from the Latin; and the main
argument of the negative critics is that it is Logical result of
this style of
impossible to suppose that a man like Alfred can criticism.
have occupied himself in turning his own vigorous
prose into indifferent verse. On this I would remark: first, does it
follow, because Alfred was a great man and a great prose-writer,
that he was also necessarily a considerable poet[895]? Secondly, if
Alfred wrote the verses, does it necessarily follow that he thought
them poor and unworthy of the trouble of making? Great writers are
not always gifted with the faculty of self-criticism; otherwise we
should not have Wordsworth taking apparently equal pleasure in the
composition of Betty Foy and of Laodamia. Indeed, on my
conscience, I believe that he liked Betty Foy the better of the
two[896]. Thirdly, even if Alfred were conscious of his limitations as a
poet, is it not possible that his conscientious spirit may have felt
bound to give as true a representation of the original as possible, by
reproducing one of its most salient features, the alternation of verse
and prose? In truth this style of criticism, if logically carried out,
would lead us very far. It would prove, for instance, that at least two
hands were concerned in the composition of the third book of
Wordsworth’s Prelude. That book contains the glorious and well-
known lines:—
But it also contains the no less well-known, but most inglorious line:
And at the Hoop alighted, famous Inn.
It would also prove (to take a closer parallel) that the late Professor
Conington never wrote a verse translation of the Aeneid. Unlike
Alfred, Mr. Conington was, as we all know, a very considerable Latin
scholar; but I must be pardoned for saying that, like Alfred, he was
not a very considerable poet. He wrote a prose translation of the
Aeneid, of which he thought so little that it was not published till
after his death; he wrote a verse translation of the same poem, of
which he evidently thought a good deal. Yet can we not imagine a
German critic a thousand years hence arguing that the author of the
prose translation could never have penned a couplet like the
following?—
But, apart from this, there are stains on Charles’s character, from
which Alfred is free; the lax morality for which Walafrid Strabo in a
curious passage places him in purgatory[943], the occasional
outbursts of cruelty which on one occasion led him to execute 4,500
rebel Saxons on a single day[944], have no counterpart in our English
hero-king.
Edward I is one of the noblest monarchs who
ever sat upon an earthly throne; brave, and dutiful, Edward I.
and true. But we have only to think of his
lawyerlike, almost tradesmanlike, way of suing for his pound of flesh
on the letter of his bond, and then recall Alfred’s comment on the
golden rule: ‘by this one law every one may know how he ought to
judge another, he needs no other law book[945],’ in order to feel the
difference between them.
It is only when I think of St. Louis that my heart
becomes a little divided. St. Louis is, to my St. Louis.
thinking, one of the most beautiful characters in
the whole of history. His saintliness is no doubt of the mediaeval
type. But this is not surprising, seeing that he lived in the thirteenth
century, the central and culminating period of the Middle Ages.
Dante, and Joan of Arc, and Thomas à Kempis are mediaeval too.
And he went on Crusade, when, according to every utilitarian
standard, he would have been better employed in governing his own
kingdom. Yet I, at least, cannot love him less, because as a ‘young
man’ he ‘saw visions,’ and went on the quest of the Holy Grail. And
he was fortunate in his biographer. What would we not give to have,
instead of Asser’s stilted and confused Latin, a memoir of Alfred in
our native tongue which might rank with Joinville’s picture of his
master? And yet in some ways the very saintliness of Louis became
a curse to France; for it shed a consecration on an evil despotism,
which finally exploded in one of the most hideous convulsions in
history:
BY THE
REV. CHARLES PLUMMER, M.A.
FELLOW AND CHAPLAIN OF
CORPUS CHRISTI COLLEGE, OXFORD
APPENDIX
‘Let every soul be subject unto the higher powers.
For there is no power but of God: the powers that be
are ordained of God.… Render therefore to all their
dues: tribute to whom tribute is due; custom to whom
custom; fear to whom fear; honour to whom honour.’—
Rom. xiii. 1, 7.
Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.
ebooknice.com